Get index of element as child relative to parent

JavascriptJquery

Javascript Problem Overview


Let's say I have this markup:

<ul id="wizard">
	<li>Step 1</li>
	<li>Step 2</li>
</ul>

And I have this jQuery:

$("#wizard li").click(function () {
	// alert index of li relative to ul parent
});

How can I get the index of the child li relative to it's parent, when clicking that li?

For example, when you click "Step 1", an alert with "0" should pop up.

Javascript Solutions


Solution 1 - Javascript

$("#wizard li").click(function () {
    console.log( $(this).index() );
});

However rather than attaching one click handler for each list item it is better (performance wise) to use delegate which would look like this:

$("#wizard").delegate('li', 'click', function () {
    console.log( $(this).index() );
});

In jQuery 1.7+, you should use on. The below example binds the event to the #wizard element, working like a delegate event:

$("#wizard").on("click", "li", function() {
    console.log( $(this).index() );
});

Solution 2 - Javascript

something like:

$("ul#wizard li").click(function () {
  var index = $("ul#wizard li").index(this);
  alert("index is: " + index)
});

Solution 3 - Javascript

Take a look at this example.

$("#wizard li").click(function () {
    alert($(this).index()); // alert index of li relative to ul parent
});

Solution 4 - Javascript

There's no need to require a big library like jQuery to accomplish this, if you don't want to. To achieve this with built-in DOM manipulation, get a collection of the li siblings in an array, and on click, check the indexOf the clicked element in that array.

const lis = [...document.querySelectorAll('#wizard > li')];
lis.forEach((li) => {
  li.addEventListener('click', () => {
    const index = lis.indexOf(li);
    console.log(index);
  });
});

<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

Or, with event delegation:

const lis = [...document.querySelectorAll('#wizard li')];
document.querySelector('#wizard').addEventListener('click', ({ target }) => {
  // Make sure the clicked element is a <li> which is a child of wizard:
  if (!target.matches('#wizard > li')) return;
  
  const index = lis.indexOf(target);
  console.log(index);
});

<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

Or, if the child elements may change dynamically (like with a todo list), then you'll have to construct the array of lis on every click, rather than beforehand:

const wizard = document.querySelector('#wizard');
wizard.addEventListener('click', ({ target }) => {
  // Make sure the clicked element is a <li>
  if (!target.matches('li')) return;
  
  const lis = [...wizard.children];
  const index = lis.indexOf(target);
  console.log(index);
});

<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

Solution 5 - Javascript

Delegate and Live are easy to use but if you won't have any more li:s added dynamically you could use event delagation with normal bind/click as well. There should be some performance gain using this method since the DOM won't have to be monitored for new matching elements. Haven't got any actual numbers but it makes sense :)

$("#wizard").click(function (e) {
    var source = $(e.target);
    if(source.is("li")){
        // alert index of li relative to ul parent
        alert(source.index());
    }
});

You could test it at jsFiddle: http://jsfiddle.net/jimmysv/4Sfdh/1/

Solution 6 - Javascript

Yet another way

$("#wizard li").click(function () 
{
    $($(this),'#wizard"').index();
});

Demo https://jsfiddle.net/m9xge3f5/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAgileMeansDoAsLittleAsPossibleView Question on Stackoverflow
Solution 1 - JavascriptredsquareView Answer on Stackoverflow
Solution 2 - JavascriptMashView Answer on Stackoverflow
Solution 3 - JavascriptKimtho6View Answer on Stackoverflow
Solution 4 - JavascriptCertainPerformanceView Answer on Stackoverflow
Solution 5 - JavascriptjimmystormigView Answer on Stackoverflow
Solution 6 - Javascripth0mayunView Answer on Stackoverflow