Reputation: 12666
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.
Upvotes: 3
Views: 10512
Reputation: 775
I like @MvanGeest's solution but there is a better way by understanding the event propagation. When an element is clicked the contained elements get the event first and trickle up through the tree. If I understand your request you would like to prevent the contained ul sending events up the tree. I think here a visual is best.
<ul>
<li></li>
<li onclick="ShowChildUL()">
<ul onclick="function(event) { event.stopPropagation() }">
<li onclick="DoSomethingFun()"></li>
<li></li>
</ul>
</li>
</ul>
In this case you will see that the onclick on the ul in the middle will stop propagation up to the li. Also event.stopPropagation() is not cross browser. I recommend this method as your onclick function.
function StopPropagation(e) {
var event = e || window.event;
[body of event handler function goes here]
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
Upvotes: 1
Reputation: 13151
you can control the above function onmouseover the list item & remove it onmouseout event of the item. But I don't know about how efficient it would be against other ways though.
Upvotes: 2
Reputation: 9661
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.
Upvotes: 11