Get child node index
you can use the previousSibling
property to iterate back through the siblings until you get back null
and count how many siblings you've encountered:
var i = 0;
while( (child = child.previousSibling) != null )
i++;
//at the end i will contain the index.
Please note that in languages like Java, there is a getPreviousSibling()
function, however in JS this has become a property -- previousSibling
.
Use previousElementSibling or nextElementSibling to ignore text and comment nodes.
How can i get the index of the child node clicked
You can have something like this:
document.querySelector("div").onclick = ({target}) => {
let index = 0;
while (target = target.previousElementSibling) {
index++;
}
console.log(index);
}
The logic is the following: you add an event listener to the container (the div, assuming you have only the span as children, otherwise you need either to filter the target
to react only to span, or add the listener to each span), and then from the span
clicked, you get the previous sibling element, until there isn't any – so you reach the first child element of the container – and you return the iteration count.
Another approach could be:
const getIndex = (target, list) =>
Array.prototype.indexOf.call(list, target)
const div = document.querySelector("div");
const span = div.querySelectorAll("span");
console.log(getIndex(span[1], span)) // 1
This is more generic: it gives you the position of an object inside an array-like object, so it works for NodeList but not only. Plus, you can pass an arbitrary list.
Replacing the previous example with this function, you will have something like:
document.querySelector("div").onclick = ({target}) => {
console.log(getIndex(target, target.parentNode.children));
}
Hope it helps!
Fastest way to find the index of a child node in parent
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.
Finding child node's index
add id to your parent element, then
let parent = document.getElementById('parentid');
let chil = parent.children;
How to get index of div in parent div?
Use Array.prototype.indexOf()
to find the child inside it's parent.children
var child = document.getElementById('findme');
var parent = child.parentNode;
var index = Array.prototype.indexOf.call(parent.children, child);
console.log(index);
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child" id="findme"></div>
<div class="child"></div>
</div>
How to get child element by index in Jquery?
If you know the child element you're interested in is the first:
$('.second').children().first();
Or to find by index:
var index = 0
$('.second').children().eq(index);
Related Topics
What Is This Practice Called in JavaScript
Why Does JavaScript Hoist Variables
Secure Random Numbers in JavaScript
How to Add Predefined Length to Audio Recorded from Mediarecorder in Chrome
How to Check If an Object Has a Key in JavaScript
Is There a Sleep Function in JavaScript
How to Store a JavaScript Function in JSON
Canvas Todataurl() Returns Blank Image
JavaScript Audio Play on Click
Failed to Execute 'Createobjecturl' on 'Url':
Node.Js Shell Command Execution
How to Determine If an Image Has Loaded, Using JavaScript/Jquery
Destructuring and Rename Property
Google Map API V3 - Set Bounds and Center
Is Onload Equal to Readystate==4 in Xmlhttprequest