This is the last in a series of posts on bubbling, delegation and how to delegate events with jQuery. You should already have read the articles What does event bubbling mean and Event Delegation in JavaScript, or have a grasp on their topics.
Event Delegation with jQuery
At the end of the last post, we had a table with hundreds of rows. Each row contained a <a />
to which we wanted to attach a click handler to. We added a single handler to the <table/>
element (we delegated the event handler to it) to capture the event.
The correct way to delegate an event handler to the <table>
for a click
on the <a />
in jQuery would be;
$('#the-table').on('click', 'a', function (e) {
alert('You clicked row #' + $(this).closest('tr').prop('rowIndex'));
e.preventDefault();
});
See it in action here. In words, we capture the element we wish to delegate the event to ($('#the-table')
) and call the on()
method on it. The event type is the first parameter (click
), and the second parameter is a selector which pinpoints the descendant(s) we wish to handle events for (a
). The third parameter is the event handler.
Inside the event handler, this
is the element the event occurred on (e.g. the <a />
that was clicked). Inside the Event object;
e.target
is the element the event occurred on (the same value asthis
).-
e.delegateTarget
is the element the event is delegated to (the<table />
element).
Note that jQuery has the same caveat as normal JavaScript when delegating an event to an element; the element you’re delegating to (the table
in this case) must exist in the DOM at the time you attach the event.
Controlling Event Bubbling with jQuery
A developer can prevent an event bubbling any further up the list of ancestors if they want to.
To do this, call the stopPropagation()
on the event object passed to an event handler. This will execute all other event handlers bound to the current element, but will not propagate up the DOM. You can see this in action here. Even though we’ve bound a click
handler to all elements in the ancestor chain, you only see alerts for the a
, span
and h1
, as the h1
handler prevents the event bubbling further.
stopImmediatePropagation()
will also prevent the event propagating, but it’ll also stop any other event handlers bound to the current element from firing.
You can check whether an event’s had it’s propagation stopped via the isPropagationStopped()
method and isImmediatePropagationStopped()
methods.
Another way a developer can stop the event propagating is by returning false
from an event handler. This is equivilant to calling stopPropagation()
and preventDefault()
. I personally recommend against using this shortcut, as it’s use can cause confusion; instead use the methods themselves to make your code more meaningful.
I read the articles about delegation and propagation and I think that I understand these topics better now.
But another question follow from the article. When we really should use stopPropagation() and stopImmediatePropagation() functions?
Lula; you can stopPropagation() and stopImmediatePropagation() to prevent other event handlers (bound to the same event type) from running. Use stopPropagation() if the event handler you wish to prevent is bound to a element further up the DOM tree, and stopImmediatePropagation() if the event handler is bound on the same element as the handler currently executing.