Is it possible to get element's numerical index in its parent node without looping?
function getChildIndex(node) {
return Array.prototype.indexOf.call(node.parentNode.childNodes, node);
}
This seems to work in Opera 11, Firefox 4, Chromium 10. Other browsers untested. It will throw TypeError if node has no parent (add a check for node.parentNode !== undefined
if you care about that case).
Of course, Array.prototype.indexOf
does still loop, just within the function call. It's impossible to do this without looping.
Note: If you want to obtain the index of a child Element
, you can modify the function above by changing childNodes
to children
.
function getChildElementIndex(node) {
return Array.prototype.indexOf.call(node.parentNode.children, node);
}
You could count siblings... The childNodes list includes text and element nodes-
function whichChild(elem){
var i= 0;
while((elem=elem.previousSibling)!=null) ++i;
return i;
}
Option #1
You can use the Array.from()
method to convert an HTMLCollection
of elements to an array. From there, you can use the native .indexOf()
method in order to get the index:
function getElementIndex (element) {
return Array.from(element.parentNode.children).indexOf(element);
}
If you want the node index (as oppose to the element's index), then replace the children
property with the childNodes
property:
function getNodeIndex (element) {
return Array.from(element.parentNode.childNodes).indexOf(element);
}
Option #2
You can use the .call()
method to invoke the array type's native .indexOf()
method. This is how the .index()
method is implemented in jQuery if you look at the source code.
function getElementIndex(element) {
return [].indexOf.call(element.parentNode.children, element);
}
Likewise, using the childNodes
property in place of the children
property:
function getNodeIndex (element) {
return [].indexOf.call(element.parentNode.childNodes, element);
}
Option #3
You can also use the spread operator:
function getElementIndex (element) {
return [...element.parentNode.children].indexOf(element);
}
function getNodeIndex (element) {
return [...element.parentNode.childNodes].indexOf(element);
}