It doesn't really matter if you specify "a"
or "li"
in the second argument - the event handler is attached to "body"
. The only thing the selector does is acting as a filter. The event handler won't be fired when none of the elements on the propagation path matched the filter "a"
. And that's it.
So consider your code as:
$body.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
});
$body.on('click', function(event) {
});
$body.on('click', function() {
});
$("ul").on('click', function() {
});
Since bubbling starts at the bottom, the "ul"
handler is fired first. Then comes the body handler, and they fire in the order the events were attached since they are all on body.
.stopImmediatePropagation()
can be used to stop propagation to handlers that are on the same level as well as any upper levels.
The upper levels of "body"
are still document
and window
(window being at the top of everything), but because you have no handlers there you will not observe that stopPropagation()
has any effect.
Another way to explain it that calling $("body").on( "click", "li", fn );
is the same as doing:
$("body").on( "click", function(e) {
var currentTarget = $(e.target).closest("li");
if( currentTarget.size() > 0 ) {
e.currentTarget = currentTarget;
fn.call(currentTarget, e);
}
});