jQuery click on li with nested ul

hookedonwinter picture hookedonwinter · Jul 27, 2010 · Viewed 10.2k times · Source

I have a list within lists. When a user clicks on a list item (<li>), I want the nested <ul> to show up. Before I started adding the nested lists, I just had it where clicking a list item would run a function. Now, clicking any of the nested lists also runs that function. Which makes sense, since they're part of the list item.

Besides wrapping a <span> around the first part of the list item and running the function on that, is there a selector that will let me run something on the parent <li> but not any of its children, specifically not the child lists and list items?

HTML:

<ul class="buckets">        
    <li class="bucket">
        <img src="arrow_group_collapsed_true.png" class="arrow">
        <img src="blue_folder.png" class="folder">
        View all
    </li>

    <li class="bucket">
        <img src="arrow_group_collapsed_false.png" class="arrow">
        <img src="blue_folder.png" class="folder">
        Groups
        <ul style="display: block;">
            <li id="group_id_15036" class="group_bucket">
                <img src="arrow_group_collapsed_true.png" class="arrow">
                <img src="blue_folder.png" class="folder">
                Group 1
            </li>
            <li id="group_id_14910" class="group_bucket">
                <img src="arrow_group_collapsed_true.png" class="arrow">
                <img src="blue_folder.png" class="folder">
                Group 2
            </li>
        </ul>
    </li>
</ul>

Javascript (not much of it, I can show more if needed):

$( 'li.bucket' ).live( 'click',
    function()
    {
        // do stuff
    })

I want a click on "Groups" or "View All" to run the click function, but a click on "Group 1" or "Group 2" should not.

Answer

MvanGeest picture MvanGeest · Jul 27, 2010

There's an official way, but in your case, it might be rather expensive:

$('li.bucket *').live('click', function(event) { event.stopPropagation() });

The li's children will now have a handler that stops the event from propagating upwards and triggering the li's handler. Please try it and see if the application isn't slowed down too much.