Event Bubbling
When an event occurs, handlers are first triggered on the innermost element, then on its parent, then one element higher, and so on, up the nesting chain. This process is called event bubbling because events bubble up from the inner element through all ancestors to window
, like a bubble of air in water.

Let's look at an example to make it clearer. There are three nested <div>
tags with click handlers on each of them.
<div id="parent">
Parent
<div id="child">
Child
<div id="descendant">Descendant</div>
</div>
</div>
Bubbling ensures that a click on #descendant
will invoke the click handler, if any: first on #descendant
itself, then on the #child
element, then on the #parent
element, then up the ancestor chain through to window
. Therefore, if you click on #descendant
in the example, then the alert for descendant
→ child
→ parent
will be displayed one after another.
Almost all events bubble, but focus
and blur
do not, so there are their bubbling counterparts, focusin
and focusout
.
event.target
property
Regardless of where you caught the event during its bubbling, you can always find out exactly where it happened. The deepest element that causes an event is called a target or original element, and it is available as event.target
.
event.target
is a reference to the original element on which the event occurred; it does not change during the bubbling process.event.currentTarget
is a reference to the current element which the bubbling has reached; it is where the event handler is currently on.
If there is an event listener registered on the outermost element, it will "catch" all clicks inside, because events will bubble up to that element. Open the console in the example and click. event.target
is always the original (and innermost) element that was clicked, and event.currentTarget
does not change.
Bubbling stop
Typically, the event will bubble up to the window
element, calling all handlers on its way. However, any intermediate handler can decide that the event has been fully handled and stop bubbling by calling the stopPropagation()
method.
If an element has several handlers for one event, then even if the bubbling stops, all of them will be executed. That is, the stopPropagation()
method only impedes the event to go further. If you need to completely stop event handling, the stopImmediatePropagation()
method is used. It not only prevents bubbling, but also stops event handling on the current element.
Do not stop bubbling unless necessary. Such termination has its pitfalls, which then have to be overcome. For example, analytics uses bubbling to track page events.