我想找到 ID 为 'whereami'
的子 div 的索引。
<div id="parent">
<div></div>
<div></div>
<div id="whereami"></div>
<div></div>
</div>
目前我正在使用这个函数来查找 child 的索引。
function findRow(node){
var i=1;
while(node.previousSibling){
node = node.previousSibling;
if(node.nodeType === 1){
i++;
}
}
return i; //Returns 3
}
var node = document.getElementById('whereami'); //div node to find
var index = findRow(node);
fiddle :http://jsfiddle.net/grantk/F7JpH/2/
问题
当有上千个div节点时,while循环要遍历每个div来统计。这可能需要一段时间。
有没有更快的方法来解决这个问题?
*注意id会随着不同的div节点变化,所以需要重新计算才可以。
最佳答案
出于好奇,我针对两个 jQuery 的 .index()
运行了您的代码和我下面的代码:
function findRow3(node)
{
var i = 1;
while (node = node.previousSibling) {
if (node.nodeType === 1) { ++i }
}
return i;
}
事实证明,jQuery 比您的实现(在 Chrome/Mac 上)慢大约 50%,而我的可以说是慢了 1%。
编辑
不能完全放弃这个,所以我又添加了两种方法:
使用 Array.indexOf
[].indexOf.call(node.parentNode.children, node);
我早期实验代码的改进,如 HBP's answer 中所示,DOMNodeList
被视为一个数组,它使用 Array.indexOf()
来确定其 .parentNode.children
中的位置,这些都是元素。我的第一次尝试是使用 .parentNode.childNodes
但由于文本节点而导致结果不正确。
使用 previousElementSibling
灵感来自 user1689607's answer ,最近的浏览器除了 .previousSibling
之外还有另一个名为 .previousElementSibling
的属性,它将两个原始语句合二为一。 IE <= 8 没有这个属性,但是 .previousSibling
已经这样做了,因此 feature detection会工作。
(function() {
// feature detection
// use previousElementSibling where available, IE <=8 can safely use previousSibling
var prop = document.body.previousElementSibling ? 'previousElementSibling' : 'previousSibling';
getElementIndex = function(node) {
var i = 1;
while (node = node[prop]) { ++i }
return i;
}
结论
在 IE <= 8 的浏览器上不支持使用 Array.indexOf()
,而且仿真速度不够快;但是,它确实提高了 20% 的性能。
使用特征检测和 .previousElementSibling
产生了 7 倍的改进(在 Chrome 上),我还没有在 IE8 上测试它。
关于javascript - 在父节点中查找子节点索引的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656921/