document.caretPositionFromPoint grabbing too high

你。 提交于 2020-01-15 12:26:14

问题


I'm working on an update to my "jump-to-anchor" add-on which is a Firefox add-on to let you right-click somewhere in a doc to (hopefully) get the closest anchor above the click point.

After submitting the add-on, I realized I could improve the algorithm by finding the actual text node where clicked, and look up from there (instead of the first children of the current clicked element). However, in my tests (against a page I happened to be reading, http://tools.ietf.org/html/rfc5323#section-2.3.2 ), the text node grabbed via document.caretPositionFromPoint is higher than expected.

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.)
});

Sound like a bug?

UPDATE:

Steps to reproduce:

  1. Install the XPI from https://github.com/brettz9/jump-to-anchor/tree/document.caretPositionFromPoint (or use cfx xpi with SDK to install from source)
  2. Go to http://tools.ietf.org/html/rfc5323#section-2.3.2
  3. Try right-clicking within section 2.3.3 (note: 2.3.3) and see it often go all the way up to the "#page-10" anchor instead of the "#section-2.3.3" anchor.

(In the current code at Github, I have the e.button === 2 check commented out, but the result is the same.)


回答1:


Turns out that the documentation on MDN is outright wrong. .caretPositionFromPoint expects that you pass coordinates relative to the current viewport.

So you'll have to use e.clientX/e.clientY!

Also, .mozInnerScreenX/Y doesn't do what you might expect it to do. Use window.innerWidth/.innerHeight if you want to check that x and y are valid coordinates within the viewport.

So here is what I tried and what seems to have worked (excerpt):

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;
    // ...
});


来源:https://stackoverflow.com/questions/24360624/document-caretpositionfrompoint-grabbing-too-high

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!