文档.caretPositionFromPoint抓取过高

document.caretPositionFromPoint grabbing too high

本文关键字:抓取 caretPositionFromPoint 文档      更新时间:2023-09-26

我正在更新我的" jump-to-anchor ";add-on,这是一个Firefox插件,可以让你右键单击文档中的某个地方,(希望)得到最近的锚点在点击点上方。

提交插件后,我意识到我可以通过查找被单击的实际文本节点来改进算法,并从那里查找(而不是当前被单击元素的第一个子元素)。然而,在我的测试中(针对我碰巧正在阅读的页面https://www.rfc-editor.org/rfc/rfc5323#section-2.3.2),通过document.caretPositionFromPoint抓取的文本节点比预期的要高。

var x = 0, y = 0;
window.addEventListener('click', function (e) {
    if (e.button === 2) { // Avoid grabbing for the actual selection // Doesn't seem to execute on the final context menu click anyways
        x = e.pageX;
        y = e.pageY;
    }
});
self.on('click', function () { // , data
    // I added the next two lines just in case the user clicked off screen
    x = x > window.mozInnerScreenX ? window.mozInnerScreenX : (x < 0 ? 0 : x);
    y = y > window.mozInnerScreenY ? window.mozInnerScreenY : (y < 0 ? 0 : y);
    var caretPosition = document.caretPositionFromPoint(x, y);
    var node = caretPosition.offsetNode;
    // Doesn't grab the right node.nodeValue here always--seems to grab too high up
    // (Then search the node for an anchor, or recursively check the deepest child of the previous element sibling on up and keep looking for previous element siblings.)
});

听起来像个bug?

更新:

复制步骤:

  1. 从https://github.com/brettz9/jump-to-anchor/tree/document.caretPositionFromPoint安装XPI(或使用cfx xpi和SDK从源代码安装)
  2. 进入https://www.rfc-editor.org/rfc/rfc5323#section-2.3.2
  3. 尝试在2.3.3节(注:2.3.3)中右键单击,可以看到它经常一直到"#page-10"锚代替"#section-2.3.3"锚。

(在Github的当前代码中,我有e.button === 2检查注释出来,但结果是相同的。)

原来MDN上的文档是完全错误的。.caretPositionFromPoint期望你传递相对于当前视口的坐标。

所以你必须使用e.clientX/e.clientY !

同样,.mozInnerScreenX/Y并没有做你可能期望它做的事情。使用window.innerWidth/.innerHeight,如果你想检查xy是视图内的有效坐标。

所以这是我所尝试的,似乎是有效的(节选):

var x = 0, y = 0;
window.addEventListener('click', function (e) {
        x = e.clientX;
        y = e.clientY;
});
self.on('click', function () { // , data
    x = Math.max(0, Math.min(innerWidth, x));
    y = Math.max(0, Math.min(innerHeight, y));
    var caretPosition = document.caretPositionFromPoint(x, y);
    var node = caretPosition.offsetNode;
    // ...
});