Fastest way to find the index of a child node in parent

dom, html, javascript

Solution

Out of curiosity I ran your code against both jQuery's `.index()` and my below code:

function findRow3(node)
{
    var i = 1;
    while (node = node.previousSibling) {
        if (node.nodeType === 1) { ++i }
    }
    return i;
}

Jump to jsperf results

It turns out that jQuery is roughly 50% slower than your implementation (on Chrome/Mac) and mine arguably topped it by 1%.

Edit

Couldn't quite let this one go, so I've added two more approaches:

Using Array.indexOf

[].indexOf.call(node.parentNode.children, node);

Improvement on my earlier experimental code, as seen in HBP's answer, the `DOMNodeList` is treated like an array and it uses `Array.indexOf()` to determine the position within its `.parentNode.children` which are all elements. My first attempt was using `.parentNode.childNodes` but that gives incorrect results due to text nodes.

Using previousElementSibling

Inspired by user1689607's answer, recent browsers have another property besides `.previousSibling` called .`previousElementSibling`, which does both original statements in one. IE <= 8 doesn't have this property, but `.previousSibling` already acts as such, therefore a feature detection would work.

(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;
    }

Conclusion

Using `Array.indexOf()` is not supported on IE <= 8 browsers, and the emulation is simply not fast enough; however, it does give 20% performance improvement.

Using feature detection and `.previousElementSibling` yields a 7x improvement (on Chrome), I have yet to test it on IE8.

Problem

I want to find the index of the child div that has the id `'whereami'`. ``` <div id="parent"> <div></div> <div></div> <div id="whereami"></div> <div></div> </div> ``` Currently I am using this function to find the index of the 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/ The Problem When there are a thousands of div nodes, the while loop has to traverse through each div to count them. Which can take a while. Is there any faster way to tackle this? *Note that the id will change to different divs node, so it will need to be able to re-calculate.

Original source

Related problems