假设以下DOM树:

<div id="edit" contenteditable="true">
  this content <a id="link" href="http://www.google.com/">contains</a> a link
</div>


然后在锚点之后创建一个范围:

var r = document.createRange();
var link = document.getElementById('link');
r.setStartAfter(link);
r.setEndAfter(link);


不出所料,其commonAncestorContainer是ID为edit的元素:

console.log(r.commonAncestorContainer);  /* => <div id="edit" contenteditable="true">…</div> */


将选择范围设置为以下范围:

var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);


现在,在窗口中查询当前选择范围并检查其commonAncestorContainer

var r2 = s.getRangeAt(0);
console.log(r2.commonAncestorContainer);


您会发现在Firefox中结果是预期的; ID为edit的相同元素。

但是,在WebKit浏览器中,选择范围的祖先容器突然成为锚点内的文本节点。 "contains",但是当您开始键入时,您会发现自己确实不在锚点内。 WTF !?

Click here for a live demo

这种行为背后是否有任何潜在的理由?任何理由假设它不是WebKit错误??

感谢您的$ .02。

最佳答案

WebKit仅允许将DOM中的某些位置用作选择边界或插入符号位置。因此,它修改使用选择的addRange()方法选择的范围以符合此要求。另请参见https://stackoverflow.com/a/14104166/96100

还有一个问题在起作用,那就是WebKit在链接的末尾有一个特殊的插入符号位置,该位置将键入的文本放置在链接之后而不是链接内。鉴于浏览器将所选内容报告为位于链接内部,因此这无疑是一个令人讨厌的黑客行为。但是,其他内联元素则不会发生这种情况,因为您可以在演示的此修改版中看到以下内容:

http://jsbin.com/EYoWuWe/7/edit

关于javascript - 将选择设置为节点边缘会使WebKit报告范围不一致,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18593541/

10-11 23:25
查看更多