从FF和谷歌浏览器的像素坐标中选择

Select from pixel coordinates for FF and Google Chrome

本文关键字:坐标 选择 像素 FF 谷歌浏览器      更新时间:2023-09-26

我已经可以为 safari 和 IE 执行此操作,就像在小提琴中一样:http://jsfiddle.net/cyk8y/(代码有点复杂或/和混乱,但它只是为了让你可以看到我想要的最终结果)。

我从这里获取了主要代码:在绝对位置设置从 A 到 B 的选择范围

在答案的评论中,Tim Down 给了我这些链接:如何使用 JavaScript 在光标下获取单词和从 FF/Webkit 中的像素位置创建一个折叠范围,以帮助我使我的代码在 FF 和谷歌浏览器中工作。

我试过了,但没有成功。

有人可以给我一个示例,从适用于FF和/或Google Chrome(和Opera)的像素坐标中进行选择。

这是我这样做

的最新尝试。表面上看起来可以工作,但我不做任何保证:这是一个不平凡的代码块,我还没有彻底测试它。

一旦我整理和测试了它,它很可能会以某种形式出现在我的 Rangy 库中。

现场演示:http://jsfiddle.net/timdown/ABjQP/8/

代码摘录(Firefox 和 Opera 位):

function getNodeIndex(node) {
    var i = 0;
    while( (node = node.previousSibling) ) {
        i++;
    }
    return i;
}
function getLastRangeRect(range) {
    var rects = range.getClientRects();
    return (rects.length > 0) ? rects[rects.length - 1] : null;
}
function pointIsInOrAboveRect(x, y, rect) {
    return y < rect.bottom && x >= rect.left && x <= rect.right;
}
function positionFromPoint(doc, x, y, favourPrecedingPosition) {
    var el = doc.elementFromPoint(x, y);
    var range = doc.createRange();
    range.selectNodeContents(el);
    range.collapse(true);
    var offsetNode = el.firstChild, offset, position, rect;
    if (!offsetNode) {
        offsetNode = el.parentNode;
        offset = getNodeIndex(el);
        if (!favourPrecedingPosition) {
            ++offset;
        }
    } else {
        // Search through the text node children of el
        main: while (offsetNode) {
            if (offsetNode.nodeType == 3) {
                // Go through the text node character by character
                for (offset = 0, textLen = offsetNode.length; offset <= textLen; ++offset) {
                    range.setEnd(offsetNode, offset);
                    rect = getLastRangeRect(range);
                    if (rect && pointIsInOrAboveRect(x, y, rect)) {
                        // We've gone past the point. Now we check which side
                        // (left or right) of the character the point is nearer to
                        if (rect.right - x > x - rect.left) {
                            --offset;
                        }
                        break main;
                    }
                }
            } else {
                // Handle elements
                range.setEndAfter(offsetNode);
                rect = getLastRangeRect(range);
                if (rect && pointIsInOrAboveRect(x, y, rect)) {
                    offset = getNodeIndex(offsetNode);
                    offsetNode = el.parentNode;
                    if (!favourPrecedingPosition) {
                        ++offset;
                    }
                    break main;
                }
            }
            offsetNode = offsetNode.nextSibling;
        }
        if (!offsetNode) {
            offsetNode = el;
            offset = el.childNodes.length;
        }
    }
    return {
        offsetNode: offsetNode,
        offset: offset
    };
}