gki*_*ely 33 html javascript dom
我想找到具有id的子div的索引'whereami'.
<div id="parent">
   <div></div>
   <div></div>
   <div id="whereami"></div>
   <div></div>
</div>
目前我正在使用此函数来查找子项的索引.
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);
小提琴:http://jsfiddle.net/grantk/F7JpH/2/
问题
 
当有数千个div节点时,while循环必须遍历每个div来计算它们.这可能需要一段时间.
有没有更快的方法来解决这个问题?
*请注意,id将更改为不同的div节点,因此需要能够重新计算.
Ja͢*_*͢ck 38
出于好奇,我针对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的答案所示,DOMNodeList被视为一个数组,它用于Array.indexOf()确定.parentNode.children其中所有元素的位置.我的第一次尝试是使用.parentNode.childNodes但由于文本节点而导致错误的结果.
使用previousElementSibling
受用户1689607的回答启发,最近的浏览器除了.previousSibling被调用之外还有另一个属性.previousElementSibling,它将两个原始陈述合二为一.IE <= 8没有此属性,但.previousSibling已经如此,因此功能检测将起作用.
(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;
    }
结论
Array.indexOf()IE <= 8浏览器不支持使用,仿真速度不够快; 但是,它确实提高了20%的性能.
使用特征检测并.previousElementSibling提高了7倍(在Chrome上),我还没有在IE8上测试它.
通过选择Array indexOf您可以使用:
  var wmi = document.getElementById ('whereami');
  index = [].indexOf.call (wmi.parentNode.children, wmi);
[仅在Chrome浏览器上测试]