Get index of element as child relative to parent
Let's say I have this markup:
<ul id="wizard"&g开发者_如何转开发t;
<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)
});
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>
Take a look at this example.
$("#wizard li").click(function () {
alert($(this).index()); // alert index of li relative to ul parent
});
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/
精彩评论