Event Propagation

Understanding Bubbling, Capturing, and the Target

Aidan McBride
6 min readNov 27, 2020
The Event Flow of Capturing and Bubbling phases

Propagation is another one of those software engineering terms that sounds much more complicated than it actually is. It is, however, a very important concept to understand and can help you debug unexpected issues in your code. Propagation also tends to be appear as a common interview topic for developer positions, so having a solid grasp on the concept is crucial. In this blog, I will walk through what propagation is, the phases an event can have, and some uses of recognizing propagation and how it works.

Event propagation can be defined as

a mechanism that defines how events propagate or travel through the DOM tree to arrive at its target and what happens to it afterward.¹

In other words, propagation is the flow of an event as it occurs in the DOM, including where it starts, its target, and where it ends. This will become much more clear by the end of this article. We will jump right in to an example to better understand the flow of an event.

A Div Within a Div

We will start by creating a nested set of divs in an html page. We will name them outer, middle, and inner to and give the same ids so we can keep track of each one. Our html should look like this:

don’t forget your script tag at the bottom!

We’re also going to add some simple CSS styling and coloring to make it clear where one div begins and the other ends. We are already importing a CSS file on line 6 of our html, so we can create the file, name it styles.css and fill it with the following code:

basic styles for our html

If we open index.html in the browser, we can see the following:

run ‘open index.html’ or open a live server to see in your browser

Visualizing Propagation

Now to set up an example of propagation we can actually see, let’s create a JavaScript file (we’ve already written the import for it in our html) and reference our elements. We can create a variable for each div using document.querySelector(), and then add an event listener for the click event on each div as well.

In this example, I am going to have each div print a different statement when it is clicked. Now, watch what happens when I click the inner most div…

One Froggy Evening 1955

For some reason, we don’t just console log “Hello my baby,”, but rather all three lines. The reason for this is, of course propagation! The target event is where we click on the inner div, but because it is nested within the two parent divs, their events are triggered as well.

The Three Phases of an Event

Events have three phases that can be captured, the capturing phase, the target phase, and the bubbling phase. The Capturing phase begins at the outer most element and moves downward or inward towards the element that calls the event. The target phase occurs on the element that has the event executed on, in this case the ‘click’ event on the center div. And finally, the Bubbling phase refers to the ‘bubbling up’ of the event, or each parent element, in order, being affected by the event.

This helpful chart describes exactly how the event phases take place, in order of capturing, target, and bubbling.

Window, to target, back to window

The even starts at the Window object, moves down all the way to the target object, then bubbles back up to the window object.

Viewing the Event Phases

We can utilize JavaScript’s built in eventPhase method to see what phase the event it is at each step of propagation. By putting our divs in an array, mapping over that array, and adding an event listener to each div, we can print out what phase the event is in.

Notice the if, else if statement on lines 16 to 22. The numbers 1, 2, and 3 correspond respectively to the Capture event, the Target event, and the Bubbling event. If you were to log the eventPhase of a non event, you would get the number 0 for no event currently occurring.

If we click on the inner most div, we will see the following in our browser console.

Notice the target event occurs after capturing but before bubbling

Notice the event starts at the outer most div and moves down, in the capturing phase, then the target phase is printed twice, and the bubbling phase ‘bubbles’ back up to the outer div.

A Note on Add Event Listener

In this code example, we use .addEventListener with three arguments. The first is the type of event, in this case ‘click’ for the mouse click on a div, the next argument is the object that receives the notification, in this case, a function we have defined named showEventPhase(). The third argument is optional but in this case is referred to as a ‘capture’ and is a boolean. The capture boolean is responsible for

indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.²

The value is defaulted to false, meaning it will show the bubbling phase starting with the target event, and then whatever phases happen above it. If set to true, the phases beginning at the outermost element and moving inward, the capturing phase, will be dispatched. This is useful to understand, and you can think of it just as the diagram from earlier, with the capture argument indicating the event capturing phase, and the value of false indicating the bubbling phase.

How to Stop Propagation

In the event you would like to stop or alter this behavior, JavaScript provides a built in method to stop propagation. By calling stopPropogation() on the event, we can change our program so it only prints the statement associated with the inner most div. By changing our JavaScript code to the following:

If we not click on the inner most div and check the console, we see that now only “Hello my baby,” has been logged and none of the parent div’s console logs have been executed!

Applications

Understanding propagation events, bubbling and capturing will come in handy likely many times in your programming journey. As demonstrated above, one great use for understanding propagation and how to stop it is when you have events nested within other elements that also have events. We can also image a situation where it is better and or easier put a button inside of a div that already has an event listener. Instead of spending too much time on CSS to reposition the button and move it in our html, we can simply stop the propagation in our buttons even listener to keep only the behavior we want to occur when we click the button.

Knowledge of propagation will also help you debug unexpected errors in your code. Understanding that an element in the phase of Capturing is occurring before the target event can help you pick out where exactly your code needs to be changed. The same goes for understanding that bubbling occurs after the target phase, where you may have to stop or change some behavior that was triggered by the event.

As always, I highly recommend going over the code in this blog and checking out my GitHub repo linked at the bottom. Also, try building your own example to track the event phases and try stopping propagation at different points! Maybe you want the inner and middle div to execute the function, but not the outer. Please leave feedback if you found this helpful or if there is anything you would like cleared up, Happy Coding!

Resources:

1.

2

3.

4.

--

--

Aidan McBride

I am a Front End Engineer and graduate of Flat Iron coding bootcamp. Currently I work in the regulatory industry using React.