我正在处理my "jump-to-anchor" add-on的更新,这是一个Firefox附加组件,可让您右键单击文档中的某个位置(希望)获得最接近点击点的锚点。
在提交附加组件后,我意识到我可以通过查找单击的实际文本节点来改进算法,并从那里查找(而不是当前单击元素的第一个子节点)。但是,在我的测试中(针对我刚刚阅读的页面http://tools.ietf.org/html/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.)
});
听起来像个臭虫?
更新
重现的步骤:
cfx xpi
从源代码安装)(在Github的当前代码中,我已将e.button === 2
检查注释掉,但结果是相同的。)
答案 0 :(得分:2)
事实证明,MDN上的文档是完全错误的。 .caretPositionFromPoint
期望you pass coordinates relative to the current viewport。
因此,您必须使用e.clientX
/ e.clientY
!
此外,.mozInnerScreenX
/ Y
并没有做您预期的事情。如果要检查window.innerWidth
和.innerHeight
是视口中的有效坐标,请使用x
/ y
。
所以这就是我尝试过的以及似乎有用的内容(摘录):
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;
// ...
});