Suthan Bala
Suthan Bala

Reputation: 3299

How to get the clicked child list item only with jQuery?

I have a multi-level unordered list. I am trying to attach the click handler to the list item and when it's clicked, I am trying to add the class active to it, but when a sub list item is clicked, the click handler is being triggered for both sub and it's parent, I think it's because it has of the same element li in all levels. How can I just attach the event to a certain level only?

Here is a sample of code, but click on the jsfiddle to see it in action:

HTML MARKUP

<ul>
  <li>test</li>
  <li>test
    <ul>
      <li>test</li>
      <li>test
    <ul></li>
  <li>test</li>
  <li>test</li>
</li>
<li>test</li>
<li>test</li>
</ul>

JAVASCRIPT

$("li").click(multiLevelClickHandler);
function multiLevelClickHandler(event)
{
    event.preventDefault();
    var $this = $(this);
    console.log($this);
    var $actives = $this.siblings().find(".active");

    if($actives.length > 0){
        $actives.removeClass('active');
        setTimeout(function(){
            $this.addClass('active');
        }, 250);
    } else {
        $this.addClass('active');
    }
}

Here is JsFiddle: http://jsfiddle.net/zcLzA/

I tried attaching the click handlers individually to each level of list items, but it's always get attached to the parent as well as the clicked list item.

Upvotes: 0

Views: 1392

Answers (3)

Brett Weber
Brett Weber

Reputation: 1907

$('li') as a selector has no qualifiers. In your JsFiddle, you are qualifying the selector using a parent to find the element, and then finding any li that is a child of a ul element within that parent. If I am understanding your requirements correctly, you are intending to target a specific level of the nested lists for the event.

To filter this further, adjust to the appropriate level by supplying more qualifiers This can be a class or element selectors (or any number of inventive methods of precisely selecting the level you want).

// class selector
$('ul.levelClass li');

or

// element selector
$('ul ul /* repeat for the number of levels */ li');

A less efficient way of handling this is to check if the event target is a child of an element that is a child of an element and so on and so forth to reach your requirements, but doing this is messy and unnecessary assuming you are only wanting to attach the handler to a specific level of your nested lists

Update

To address your comment, and the issue you are facing, following the suggestions in other answers (event.stopPropagation() or event.stopImmediatePropagation()) combined with my suggestions will solve this. If you stop the event from bubbling after selecting the level you wish to attach the handler to, you stop the parent from receiving the event

An example of this in code:

elemContainer.find('ul.nestedLevelClass li').on("click", SpecificLevelHandler)

var SpecificLevelHandler = function(oEvent)
{
    oEvent.stopPropagation() // stop the event from bubbling up 
    // oEvent.stopImmendiatePropagation() // stop the event from firing any other handlers at all
    var oElem = $(this);
    /* Handle the event */
}

Upvotes: 1

Ryaden
Ryaden

Reputation: 108

Use event.stopPropagation() at the end of your multiLevelClickhandler() function.

Upvotes: 1

Mister Epic
Mister Epic

Reputation: 16743

Use event.stopPropagation();:

function multiLevelClickHandler(event){
    event.stopPropagation();

This stops the event from bubbling up the DOM.

http://jsfiddle.net/zcLzA/2/

ref: http://api.jquery.com/event.stoppropagation/

Upvotes: 3

Related Questions