【问题标题】:Select from pixel coordinates for FF and Google Chrome从像素坐标中选择 FF 和 Google Chrome
【发布时间】:2012-06-28 20:51:06
【问题描述】:

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

我从这里获取了主体代码:Set a selection range from A to B in absolute position

在答案的 cmets 中,Tim Down 给了我这些链接:How to get a word under cursor using JavaScriptCreating a collapsed range from a pixel position in FF/Webkit 以帮助我使我的代码在 FF 和 Google Chrome 中运行。

我试过了,但没有成功。

谁能给我一个从像素坐标中进行选择的示例,该坐标适用于 FF 和/或 Google Chrome(和 Opera?)。

【问题讨论】:

  • 我正在努力。最新未完成但可正常工作的版本:jsfiddle.net/timdown/ABjQP/2
  • @TimDown 这SO令人印象深刻!非常感谢!!!!!!
  • 对我来说似乎在 Opera 中工作。我知道 Opera 支持 Range 和 document.elementFromPoint()getClientRects() 方法,所以它应该可以工作。
  • 真的很奇怪。第一次使用opera,刚下载完,就不行了。现在,一天后,每次我尝试,它都有效。 (对于我们第一次使用 Opera - 对于 Mac 来说,这似乎是一个错误)。总之,它适用于 Opera。
  • jsfiddle.net/timdown/ABjQP/2 中,你是添加了stackoverflow.com/questions/11191136/… 的代码还是只是ff、chrome 和opera 的方式? (因为我想试试只有 getClientRectselementFromPoint 的版本是否适用于 safari 和 ie)

标签: javascript firefox google-chrome selection


【解决方案1】:

这是我的最新尝试。从表面上看似乎可行,但我不能保证:这是一段不平凡的代码,我还没有彻底测试过。

一旦我整理和测试了它,它很可能会以某种形式出现在我的 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
    };
}

【讨论】:

  • I just saw a bug, it's when you write something like createSelectionFromPoint(100, 100, 30, 30); (when the selection is from down to top).也许你可以通过if(endY&lt;startY){var t=startX;startX=endX;endX=t;t=startY;startY=endY;endY=t;} 解决这个问题,但我不知道在哪里写。请问你能纠正这个吗?
  • @user1365010:哦,你想做一个反向选择吗?很公平,这并不太难,但增加了更多复杂性并且在 IE 中不起作用(在 IE 中以编程方式创建向后选择是不可能的)。正在修改...
  • 是的,但是您可以通过正常选择但使用倒置坐标来模拟这一点
  • @user1365010:选择确实有方向。例如,它会影响箭头键的行为。
  • 太酷了,再次感谢!我可以做的一些有趣的事情是在用户想要选择另一件事时选择一些东西:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2013-12-31
  • 1970-01-01
  • 2020-05-13
相关资源
最近更新 更多