Javascript range.setStartBefore()在Chrome和FireFox中的表现非常奇怪。这就是它的工作原理吗?

Javascript range.setStartBefore()在Chrome和FireFox中的表现非常奇怪。这就是它的工作原理吗?,javascript,dom,webkit,range,Javascript,Dom,Webkit,Range,我写了一封信 基本上,我要做的是在contenteditable区域中的DIV之前选择元素。我遇到了我不理解的行为,我发现自己在想,这是不是应该是这样的 考虑以下标记: <DIV contenteditable="true">foo<div id="test">bar</div></div> 不幸的是,在jsfiddle.net生成一些jsfiddle错误时尝试这个方法,所以我把它放了起来 我得到的范围在FireFox和Chrome之间非常不同

我写了一封信

基本上,我要做的是在contenteditable区域中的DIV之前选择元素。我遇到了我不理解的行为,我发现自己在想,这是不是应该是这样的

考虑以下标记:

<DIV contenteditable="true">foo<div id="test">bar</div></div>
不幸的是,在jsfiddle.net生成一些jsfiddle错误时尝试这个方法,所以我把它放了起来

我得到的范围在FireFox和Chrome之间非常不同

Chrome返回一个startContainer,它的startOffset为3,正好指向文本“foo”。这就是我所期望的。光标将移动到该位置

FireFox返回可编辑DIV的startContainer,偏移量为1,指向整个textnode。不是我所期望的。如果您聚焦div,光标将指向“bar”的左侧

如果HTML更改为:

<DIV contenteditable="true"><div>foo</div><div id="test">bar</div></div>
重复这个实验,FireFox返回一个startContainer,其中DIV可编辑,startOffset为1。光标保留在“bar”之前。考虑到上次测试的结果,这对我来说是有意义的

但是,Chrome返回一个startContainer,其textnode的长度为0,nextSibling previousSibling均为null,但父节点设置为div id=“test”。光标保持在“栏”的前面


这是正确的行为吗?当你得到这样的射程时,你该怎么办?还是在刚坏之前/之后

问题在于WebKit如何在选择范围时规范化该范围,而不是范围本身。在WebKit和Mozilla之间,甚至IE>=9和Opera之间,基本的范围方法(如setStartBefore)始终有效

范围的存在不仅仅是为了服务选择,范围边界可以存在于任何类型的节点中,而不仅仅是文本节点。对于非基于文本的节点文本节点、注释、cdata,范围边界表示为父节点内边界之前的子节点数。在所有浏览器中都是如此。只有当范围被添加到选择中时,事情才会不一致


在Chrome中,第二个示例将插入符号放置在条形文本节点的开头。请参见

,为了确保我没有做一些完全愚蠢的事情,医生们说:谢谢再次回复。。你帮了我大忙。但我不明白的是,为什么它不将插入符号放在上一个文本节点的末尾。如果我要求在div之前提供一个范围,那么它不应该为我提供一些实际上在div之前的东西吗?这就是我感到非常困惑的地方。为什么我会在Chrome中得到一个零宽度的文本节点作为startContainer,它既没有上一个兄弟节点,也没有下一个兄弟节点?@YermoLamers:是之前设置的范围,还是将该范围添加到选择中时发生的事让你感到困惑?重新。Chrome的东西,我无法复制,所以我可能做错了或者没有抓住要点。好的,我用我发布的代码重做了这个实验。现在我也无法重现我所看到的。我发誓在两个div之间尝试setStartBefore时得到的是空的0长度文本节点。i、 e.第二个案件。这些0长度的文本节点没有下一个或上一个同级。昨天我做了十几次这个实验,但在整个过程中没有关闭和重新启动浏览器。我想可能是我犯了一个斜视错误,但8小时后我怀疑不是。很奇怪。我得看看能不能复制出来。该死
<DIV contenteditable="true"><div>foo</div><div id="test">bar</div></div>