2012-02-18 26 views

回答

0

是的,没有。

这是不可能在一般情况下,如果你想创建仅一个范围,因为范围不能在大多数浏览器中的多个位置选择文本(例如,如果你的身高“像素的矩形”不止一个文本线)。请注意,您提到的“像素矩形”更精确地说是一个裁剪矩形。

但是,如果您同意拥有倍数范围,则可以这样做。主要想法是为您的剪辑矩形的每一行创建一个范围。选择不会显示在屏幕上(因为大多数浏览器不支持多选),但至少可以提取剪切矩形中的文本。这是我是如何实现它:

var columnModeSelection = { 
    startX:10, 
    startY:10, 
    endX:20, 
    endY:30, 
    selectedTextRanges:null // an Array of Range 
}; 
createColumnModeSelection(); 

/** 
Emulates MSIE function range.moveToPoint(x,y) by returning the selection node info which corresponds to the given x/y location. 
@param x the point X coordinate 
@param y the point Y coordinate 
@return the node and offset in characters as {node,offsetInsideNode} (e.g. can be passed to range.setStart) 
*/ 
function getSelectionNodeInfo(x, y) { 
    var startRange = document.createRange(); 
    window.getSelection().removeAllRanges(); 
    window.getSelection().addRange(startRange); 

    // Implementation note: range.setStart offset is 
    // counted in number of child elements if any or 
    // in characters if there is no childs. Since we 
    // want to compute in number of chars, we need to 
    // get the node which has no child. 
    var elem = document.elementFromPoint(x, y); 
    var startNode = (elem.childNodes.length>0?elem.childNodes[0]:elem); 
    var startCharIndexCharacter = -1; 
    do { 
     startCharIndexCharacter++; 
     startRange.setStart(startNode, startCharIndexCharacter); 
     startRange.setEnd(startNode, startCharIndexCharacter+1); 
     var rangeRect = startRange.getBoundingClientRect(); 
    } while (rangeRect.left<x && startCharIndexCharacter<startNode.length-1); 

    return {node:startNode, offsetInsideNode:startCharIndexCharacter}; 
} 

/** 
Copy user selection to clipboard in plain text. 
Multibrowser: supported under MSIE and WebKit 
*/ 
function createColumnModeSelection() { 
    // build a TextRange for each line to select 
    var startY = columnModeSelection.startY; 
    columnModeSelection.selectedTextRanges=new Array(); 
    while (startY<columnModeSelection.endY) { 

     // select the line 
     var range = null; 
     if (document.selection) { 
      // MSIE 
      // Implementation note: the TextRange cannot be created from pixel 
      // coordinates, only the start point can. Thus, we are creating two 
      // TextRanges with a start point and set the end point of the first 
      // range to the start point of the end range. 

      // set the start point    
      range = document.selection.createRange(); 
      range.moveToPoint(columnModeSelection.startX, startY); 
      // set the end point   
      var endRange = document.selection.createRange(); 
      endRange.moveToPoint(columnModeSelection.endX, startY); // set the first line end 
      range.setEndPoint("EndToStart", endRange); 
      // create the selection 
      range.select(); 
     } else { 
      // other browsers 
      var lineStartNodeInfo = getSelectionNodeInfo(columnModeSelection.startX, startY); 
      var lineEndNodeInfo = getSelectionNodeInfo(columnModeSelection.endX, startY); 
      range = document.createRange(); 
      range.setStart(lineStartNodeInfo.node, lineStartNodeInfo.offsetInsideNode); 
      range.setEnd(lineEndNodeInfo.node, lineEndNodeInfo.offsetInsideNode+1); 
     } 

     // keep the selection for later usage 
     if (range!=null) { 
      columnModeSelection.selectedTextRanges.push(range); 
     } 

     // go to the next line 
     var elem = document.elementFromPoint(columnModeSelection.startX, startY); 
     var lineHeight = elem.clientHeight; 
     startY += lineHeight; 
    } 

    // clear the last selected range 
    if (document.selection) { 
     // MSIE 
     document.selection.empty(); 
    } else { 
     // Safari, Firefox 
     window.getSelection().removeAllRanges(); 
    } 
} 

此已根据以下浏览器进行测试:

  • MSIE 7,MSIE 9
  • 火狐5,火狐10
  • 铬9
  • Safari 5