javascript - 像素范围

标签 javascript html dom

如果我有一个范围,我可以通过 getBoundingClientRect 得到它的边界矩形.反过来可能吗?也就是说,给定一个像素矩形创建一个范围。

最佳答案

是也不是。

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

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

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
  • Chrome 9
  • Safari 5

关于javascript - 像素范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9345275/

相关文章:

html - CSS - 减少过滤器中文本的方法,这样它就不会占用太多屏幕空间

javascript - data-ng-change 无法将参数传递给函数

javascript - 图像没有显示,即使我试图从 html 数据表中获取图像并将其显示到 div 中

php - 为什么 PHP 会干扰我的 HTML5 MP4 视频?

javascript - 如何避免 jquery ui 工具提示出现在子 div 中?

java - com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException : Invalid byte 2 of 4-byte UTF-8 sequence (XML)

javascript - 是否存在 JavaScript DOM 无法访问的任何 CSS 属性?

javascript - 如何根据选择器查询检查 javascript DOMElement

javascript - 使用 Javascript 或 JQuery 为表单变量创建 ID(或更改它)

javascript - 添加js时dropdownlist不保存