作者:小色米虫_524 | 2023-09-01 18:29
我想找到给定DOM节点的索引.这就像做的反过来
document.getElementById('id_of_element').childNodes[K]
我想提取K
给定的值,我已经有了对子节点和父节点的引用.我该怎么做呢?
1> Matthew..:
在所有版本的Safari,FireFox,Chrome和IE> = 9中,最短的方式,没有任何框架:
var i = Array.prototype.indexOf.call(e.childNodes, someChildEl);
注意:将`e.childNodes`替换为`e.children`以查找其兄弟_elements_中元素的索引 - 而不是兄弟_nodes_,其中包括文本和注释节点.
@StevenLu这是故意的.见[ECMA-262第5版](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)第244页(pdf中的145),第15.4节的最后一个注释.4.14:"`indexOf`函数是故意通用的;它不要求它的_this_值是一个**Array**对象.因此它可以转移到其他类型的对象用作方法.是否`indexOf `函数可以成功应用于宿主对象是依赖于实现的."
为什么我们不能做像'e.parentNode.childNodes.indexOf(e)`这样的事情?编辑:我刚试过它.`NodeList`不是一个真正的`Array`所以我们必须通过它的原型引入`array`的`indexOf`的impl.令我惊讶的是,'Array`的`indexOf`在`NodeList`上起作用,无论是有意还是巧合.
以数组分配为代价,它可以缩短为`[] .indexOf.call(children,el)`,除非浏览器兼容性声明不符合(虽然我发现这很令人惊讶).
@StevenLu你的第一个问题:NodeList上的indexOf没有在DOM规范中定义,甚至在DOM4中也没有定义.你的最后一点:这是有意的.数组方法足够通用,几乎可以在任何具有length属性的函数上运行.
2> some..:
要短一点,期望元素在elem中,返回k.
for (var k=0,e=elem; e = e.previousSibling; ++k);
在Justin Dearing的评论之后,我回顾了我的回答并添加了以下内容:
或者如果你喜欢"同时":
var k=0, e=elem;
while (e = e.previousSibling) { ++k;}
最初的问题是如何找到现有DOM元素的索引.我在本回答中的上述两个示例都希望elem是一个DOM元素,并且该元素仍然存在于DOM中.如果你给它们一个空对象或没有previousSibling的对象,它们将失败.更简单的方法是这样的:
var k=-1, e=elem;
while (e) {
if ( "previousSibling" in e ) {
e = e.previousSibling;
k = k + 1;
} else {
k= -1;
break;
}
}
如果e为null或者其中一个对象中缺少previousSibling,则k为-1.
@some +1优雅 - 非常好的解决方案和谢谢.