soon to become just became even more concise).
addEventListener(type, listener[, useCapture])
function, specifically the third parameter. jQuery seems to only support bubbling. The bind() method has a parameter called preventBubbling which can only be set without a handler argument and seems to be equivalent to attaching a function which stops propagation of the event (we'll get into that later in this post). It is not equivalent to setting addEventListener's useCapture parameter to true.
On to the difference between bubbling and capturing. I give you the following html:
<div id="parent"> <div id="child"></div> </div>
If the same event type was attached to #parent and #child there would be two possibilities as to their order, depending on the useCapture parameter:
In the bubbling phase (useCapture = false), the child event handler is executed first followed by the parent. In the capturing phase (useCapture = true), the parent is executed followed by the child. All of this assuming the event was triggered on the child. Simple so far right?
What if our #child grew into a #teenager, got pregnant and had a #baby?
You hook up all your events like so (using click as an example):
document.getElementById('baby') .addEventListener('click', click_handler, true); document.getElementById('teenager') .addEventListener('click', click_handler, false); document.getElementById('parent') .addEventListener('click', click_handler, false); document.addEventListener('click', click_handler, false);
And click on #baby. Since you set #baby's useCapture to true, you might expect the events to fire using the capture phase/bottom up i.e. document - #parent - #teenager - #baby. In actuality, they will fire in bubbling order — from #baby down to the document.
What has happened? It turns out that the browser evaluates the event order in a specific order — recursively! What?! Yes, but settle down, this is not as crazy as it sounds; in fact it a completely sensible way to handle event ordering.
Your click on #baby is first evaluated between the document and its direct child (> #parent) which is on the same "branch" as the event target (#baby). The documents useCapture is set to false (bubble) so it will do #parent's event first. But #parent has its own child elements and order of events. So the next phase begins between #parent and its direct child (#parent > #teenager). #parents useCapture is false too; making us resolve the #teenager > #baby before firing the #parent's handler. This happens for the #teenager too until the phase stops at #baby. This ends the phase at which point the events finally begin firing.
This is obviously one example, that is why I have made a small demo in which you can play around with event capturing and bubbling:View Demo
- QuirksMode.org on Events Order.