32

The NodeList don't have a indexOf(element) method? So, how can I get the element index?

The Student
  • 27,520
  • 68
  • 161
  • 264

5 Answers5

75

You can use Array.prototype.indexOf.call() like this

let nodes = document.getElementsByTagName('*');
Array.prototype.indexOf.call(nodes, document.body);
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • 12
    To make it mega obvious, usage is like `Array.prototype.indexOf.call(haystack, needle);` – wkille Sep 23 '20 at 09:36
28

The NodeList object is an Array-like object. So it's possible to "convert" it into an Array using Array.prototype.slice.call()

var arr = Array.prototype.slice.call(yourNodeListObject); // Now it's an Array.
arr.indexOf(element); // The index of your element :)

On browsers that support ES6 you can also do this with Array.from()

const arr = Array.from(yourNodeListObject);

or using the spread operator ...

const arr = [...yourNodeListObject];
Brandon
  • 3,572
  • 2
  • 12
  • 27
Golmote Kinoko
  • 898
  • 5
  • 8
  • You can use it like this: `var listOfElements = Array.prototype.slice.call(node.parentElement.children), // Now it's an Array. indexInList = listOfElements.indexOf(node);` – Marian07 Jul 13 '22 at 17:42
15

By iterating over the elements, and checking if it matches.

Generic code that finds the index of the element within it's parents childNodes collection.

function index(el) {
    var children = el.parentNode.childNodes,
        i = 0;
    for (; i < children.length; i++) {
        if (children[i] == el) {
            return i;
        }
    }
    return -1;
}

Usage:

// should return 4
var idx = index(document.body.childNodes[4]);

EDIT: I can't delete an accepted answer, but @kennebec's answer below is much better, which I'll quote verbatim:

You can use Array.prototype.indexOf.call() like this

let nodes = document.getElementsByTagName('*');
Array.prototype.indexOf.call(nodes, document.body);
Martijn
  • 11,964
  • 12
  • 50
  • 96
2

Just add one line in your script:

NodeList.prototype.indexOf = Array.prototype.indexOf;   // for IE11

Then use indexOf as usual:

var index = NodeList.indexOf(NodeElement);
  • it seems to work, OK. But why ? could you explain ? – Chrysotribax Sep 27 '21 at 11:36
  • More explanation would be nice. But on face value it seems to be just a roundabout way of casting into an array which is why it works the same way as the answers above. – 4127157 Apr 19 '22 at 16:23
1

Let us say you have the following line:

const list=document.querySelectAll('.some_class .someother_class');

list will be a nodelist. So we can convert the nodelist to an array and create a new array of indexes as follows:

const indexArr= [...list].map( element => return [...list].indexOf(element) );

indexArr contains all the indexes of elements in the original list.