简体   繁体   中英

Get index of element as child relative to parent

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.

$("#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() );
});

something like:

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

Take a look at this example .

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

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 li s 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>

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/

Yet another way

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

Demo https://jsfiddle.net/m9xge3f5/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM