To check if an element is a child of a parent with JavaScript, we can use the parent element's contains method. const contains = (parent, child) => { return parent !== child && parent. contains(child); };
$("#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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With