Reputation: 13727
According to the jQuery docs
Returning false from an event handler will automatically call event.stopPropagation() and event.preventDefault(). A false value can also be passed for the handler as a shorthand for function(){ return false; }. So, $("a.disabled").on("click", false); attaches an event handler to all links with class "disabled" that prevents them from being followed when they are clicked and also stops the event from bubbling.
So when I create a click event:
$('#sidebar').on("click", ".toggle", function() {
$(this).parents("p").next("ul").toggle(400);
return false;
});
I would expect the click to not register since it would not have a chance to propagate from .toggle
to #sidebar
The only explanation I've come up with would be that if this was allowed to happen it would make the on()
function fairly pointless, so perhaps it's bypassed in this case?
What rules does on()
follow as far as bubbling?
Upvotes: 2
Views: 939
Reputation: 30666
Actually, the handler is attached to the element #sidebar
, not to the .toggle
elements.
So when you click on an inner element, the event bubbles up until it reaches `#sidebar' and then only the handler is executed. Returning false in the handler, will then stop the propagation further up.
The documentation for .on() mentions this through an example:
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, this example attaches a handler to 1,000 elements:
$("#dataTable tbody tr").on("click", function(event){
alert($(this).text());
});
A delegated-events approach attaches an event handler to only one element, the tbody, and the event only needs to bubble up one level (from the clicked tr to tbody):
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});
Upvotes: 5
Reputation: 36592
In order for on()
to work, the click event must bubble up to the calling element, in this case #sidebar
. on()
then looks at the target of the click to determine if it is .toggle
and fire the function accordingly.
You can pass the event into your handler and add
to prevent other bound handlers from firing.
Upvotes: 4
Reputation: 108500
The click event in your example is attached to #sidebar
, and if you return false from the handler, it will not propagate further up the DOM tree.
Here is an example fiddle: http://jsfiddle.net/QymkW/
This is one of the reasons for the recent change in the syntax for event delegation, using the .live()
syntax, one would think that the event was attached to the element you pass in the chain, but it was always the document
. This was confusing in terms of propagation.
Using the .on()
syntax, you now paint a better picture of what is really going on. The event is attached to the element passed, and then you can add a second argument if you want to delegate events from descendants. So the propagation "must" happen between the delegated descendants and the element for the delegation to work, but you can still prevent bubbling from the element that attached the event (in your case #sidebar
)
Upvotes: 2