Val*_*ero 3 javascript firefox google-chrome range
我正在尝试制作一个小文本编辑器.
当我选择一个文本时,我想知道所选文本是单独存在于a span还是a中div,然后我想要更改此元素的样式.
示例:
<span style="font-size:12px">Hola</span>
Run Code Online (Sandbox Code Playgroud)
如果我选择Hola我想要检索父节点<span style="font-size:12px">Hola</span>
<span style="font-size:56px">
Hola <span style="font-size:12px">Hello</span>
</span>
Run Code Online (Sandbox Code Playgroud)
如果我选择Hello,我只想检索<span style="font-size:12px">Hello</span>
现在,当我在Chrome中试用时,我得到了正确的结果
range.startContainer.parentNode;
Run Code Online (Sandbox Code Playgroud)
但是在第二个例子中我使用Firefox检索
<span style="font-size:56px">
Hola <span style="font-size:12px">Hello</span>
</span>
Run Code Online (Sandbox Code Playgroud)
如何在Chrome和Firefox中获得相同的结果?
您的问题是,当一个或两个选择边界与DOM节点边界重合时,浏览器之间的选择工作略有不同.例如,如果用户使用以下HTML在页面内容中选择了单词"bar"
<p>foo<i>bar</i></p>
Run Code Online (Sandbox Code Playgroud)
...选择开始有四种不同的可能位置,所有这些位置在视觉上与用户完全相同:
<p>元素的一个子节点之后(节点<p>,偏移1)<i>元素为零之后(节点<i>,偏移0)大多数浏览器在实践中不允许所有这些位置,但遗憾的是不同的浏览器做出了不同的选择.在Firefox中,您所做的选择选择整个<span>元素,选择范围startContainer是<span>父节点.您可以通过检查范围来检测它,看它是否选择单个节点:
function rangeSelectsSingleNode(range) {
var startNode = range.startContainer;
return startNode === range.endContainer &&
startNode.hasChildNodes() &&
range.endOffset === range.startOffset + 1;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用它来检测您拥有的选择类型并相应地获取所选元素:
var selectedElement = null;
if (rangeSelectsSingleNode(range)) {
// Selection encompasses a single element
selectedElement = range.startContainer.childNodes[range.startOffset];
} else if (range.startContainer.nodeType === 3) {
// Selection range starts inside a text node, so get its parent
selectedElement = range.startContainer.parentNode;
} else {
// Selection starts inside an element
selectedElement = range.startContainer;
}
Run Code Online (Sandbox Code Playgroud)