Event Bubbling

4 Min. Read
Sep 1, 2019

What is Event Bubbling?

Event bubbling is a type of event propagation where the event first triggers on the innermost target element, and then successively triggers on the ancestors (parents) of the target element in the same nesting hierarchy till it reaches the outermost DOM element or document object(Provided the handler is initialized). It is one way that events are handled in the browser. Events are actions done by the user such as a button click, changing a field etc. Event Handlers are used to perform methods according to the event that has occurred. For instance: The steps that need to be done once a button has been clicked or once the webpage completes loading

Event bubbling is a frequent term you might have come across on your JavaScript travels. It relates to the order in which event handlers are called when one element is nested inside a second element, and both elements have registered a listener for the same event (a click, for example). But event bubbling is only one piece of the puzzle. It is often mentioned in conjunction with event capturing and event propagation. And a firm understanding of all three concepts is essential for working with events in JavaScript.

Overview

Consider the DOM structure where there are 3 elements nested in the following order: - i) Element 1 (Div) whose on-click handlers is handler1() - ii) Element 2 (Span) whose on-click handlers is handler2() - iii) Element 3 (Button) whose on-click handlers is handler3().

A figurative description of the above instance is given below:

Fig: Description of the instance described above

1
2
3
4
5
<div id=”Element1” onclick=”handler1()”>
  <span id=”Element2” onclick=”handler2()”>
    <input type=”button” id=”Element3” onclick= “handler3()”/>
  </span>
</div>

When a button is clicked, an event handler for Element 3 is triggered first, then event bubbles up and the handler for immediate parent element - Element 2 is called, followed by the handler for Element 1 and so on till it reaches the outermost DOM element.

Event handling order: handler3() - > handler2() -> handler1()

The innermost element from where the event is triggered is called the target element. Most of the browsers consider event bubbling as the default way of event propagation. However, there is another approach for event propagation known as Event Capturing, which is the direct opposite of event bubbling, where event handling starts from the outermost element (or Document) of the DOM structure and goes all the way to the target element, executing the target element handler last in order.

Use of Event Bubbling

To handle cases where one event has more than one handler, event bubbling concept can be implemented.The major use of event bubbling is the registration of default functions present in the program. It is not necessary to implement event bubbling; it may become complicated for the users to keep track of the actions getting executed because of an event.

Differences between Event Propagation, Event Bubbling and Event Capturing

Event Propagation

Let’s start with event propagation. This is the blanket term for both event bubbling and event capturing. Consider the typical markup to build a list of linked images, for a thumbnails gallery for example:

1
2
3
4
5
 <ul>
    <li><a href="..."><img src="..." alt=""></a>
    <li><a href="..."><img src="..." alt=""></a>
    <li><a href="..."><img src="..." alt=""></a>
</ul>

A click on an image does not only generate a click event for the corresponding img element, but also for the parent a, for the grandfather li and so on, going all the way up through all the element’s ancestors, before terminating at the window object.

In DOM terminology, the image is the event target, the innermost element over which the click originated. The event target, plus its ancestors, from its parent up through to the window object, form a branch in the DOM tree. For example, in the image gallery, this branch will be composed of the nodes: img, a, li, ul, body, html, document, window.

This branch is important because it is the path along which the events propagate (or flow). This propagation is the process of calling all the listeners for the given event type, attached to the nodes on the branch. Each listener will be called with an event object that gathers information relevant to the event. The propagation is bidirectional, from the window to the event target and back. This propagation can be divided into three phases:

  • From the window to the event target parent: this is the capture phase
  • The event target itself: this is the target phase
  • From the event target parent back to the window: the bubble phase

What differentiates these phases is the type of listeners that are called.

The Event Capture Phase:

In this phase only the capturer listeners are called, namely, those listeners that were registered using a value of true for the third parameter of addEventListener:

1
el.addEventListener('click', listener, true)

If this parameter is omitted, its default value is false and the listener is not a capturer. So, during this phase, only the capturers found on the path from the window to the event target parent are called.

The Event Bubbling Phase:

During the event bubbling phase only the non-capturers will be called. That is, only the listeners registered with a value of false for the third parameter of addEventListener().

1
2
el.addEventListener('click', listener, false) // listener doesn't capture
el.addEventListener('click', listener) // listener doesn't capture

Note that while all events flow down to the event target with the capture phase, focus, blur, load and some others, don’t bubble up. That is, their travel stops after the target phase. Therefore, at the end of the propagation, each listener on the branch has been called exactly once.