35

As per the jQuery api, the complementary operation to .get(), which accepts an index and returns a DOM node, .index() can take a DOM node and returns an index. Suppose we have a simple unordered list on the page:

<ul>
  <li id="foo">foo</li>
  <li id="bar">bar</li>
  <li id="baz">baz</li>
</ul>

.index() will return the position of the first element within the set of matched elements in relation to its siblings:

alert('Index: ' + $('#bar').index();

We get back the zero-based position of the list item:

Index: 1

I just want to know, how can we do the same using JavaScript??

4
  • I'm not suggesting you should always use jQuery, but out of curiosity, why do you want to do this in pure JS? Commented Dec 1, 2012 at 9:17
  • 2
    @JamWaffles: I use jQuery mostly, due to its "The Write Less, Do More" nature. So, I had asked this question just for my knowledge and let others know, what "The Write Less, Do More" really means from this example. Hope you got my point! Commented Dec 1, 2012 at 10:45
  • possible duplicate of Finding DOM node index Commented Dec 1, 2012 at 17:53
  • 1
    @AndrewWhitaker It should be noted that the answers in the listed duplicate look for the index without testing the type of the node (which may be a text for example). That's why they don't return the same result than jquery's index (as is the question) which is what is generally useful. Commented Dec 3, 2012 at 7:58

5 Answers 5

22

You can build your own function :

function indexInParent(node) {
    var children = node.parentNode.childNodes;
    var num = 0;
    for (var i=0; i<children.length; i++) {
         if (children[i]==node) return num;
         if (children[i].nodeType==1) num++;
    }
    return -1;
}

Demonstration (open the console)

Sign up to request clarification or add additional context in comments.

4 Comments

Really like this answer! Why do you need to end off with return -1? The code will never hit that. If you pass an invalid element, you will get an error.
@Jessica The usual convention for index functions is to return -1 when an element isn't found, not an error (or undefined as it would be without the last line)
Thanks! Do you know the source for jquery's index() is?
Why not use parentNode.children instead of parentNode.childNodes? It could allow using indexOf instead of increasing num manually.
22

I've modified Travis J answer to not include TextNodes and made a function out of it.

You can run it in the console and see (on stackoverflow).

Classic way:

function getNodeIndex( elm ){ 
    var c = elm.parentNode.children, 
        i = c.length;
        
    while(i--) 
      if( c[i] == elm ) 
        return i
}

With ES2015:

const getNodeIndex = elm => [...elm.parentNode.children].findIndex(c => c == elm)

// or

const getNodeIndex = elm => [...elm.parentNode.children].indexOf(elm)

Demo:

const getNodeIndex = elm => [...elm.parentNode.children].indexOf(elm)
<button onclick="console.log(  getNodeIndex(this)  )">get index</button>
<button onclick="console.log(  getNodeIndex(this)  )">get index</button>
<button onclick="console.log(  getNodeIndex(this)  )">get index</button>


I also want to point to another thread on the same matter, which has a great answer (for people seeking older IE support)

Comments

11

No loops needed, call Array#indexOf on .parentElement.children:

const element = document.querySelector('#baz');

[].indexOf.call(element.parentElement.children, element);
// => 2

You can even call it on a random list of elements, just like you can in jQuery:

const list = document.querySelectorAll('li');
const element = document.querySelector('#baz');

[].indexOf.call(list, element);
// => 2

1 Comment

This should be more highly upvoted, it accomplishes the same thing as all of the other answers do in a single line of code - brilliant
1

You can find this information out by going up the dom tree using previousElementSibling and incrementing.

var getElementIndex(element) {
    if (!element) {
        return -1;
    }
    var currentElement = element,
        index = 0;

    while(currentElement.previousElementSibling) {
        index++;
        currentElement = currentElement.previousElementSibling;
    }
    return index
}

getElementIndex(document.getElementById('#bar'));

here is the browser support for previousElementSibling:

https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/previousElementSibling

Comments

0

Index can be found in this way

    Array.from(children).findIndex(element => element.id === "bar")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.