Register to get access to free programming courses with interactive exercises

Capturing and bubbling JS: DOM API

Suppose we have two nested elements, each with a click event handler. If you click on an area of an external element that doesn't affect an internal one, then the handler bound to this external element will be executed. If the inner element is clicked on, then the outer element will also be clicked on automatically, which means that both events will occur.

button.addEventListener('click', () => alert('Boom 1!'));
div.addEventListener('click', () => alert('Boom 2!'));

You may wonder what order these events will be executed in after clicking the button. In general, an event will pass through the tree, starting from the root and going to the deepest element that the event was triggered on, and then in the opposite direction. The journey of an event up and down the tree is called its stages or phases, we'll see more about that below.


When an event has just occurred, it starts moving through the DOM tree, starting from the root node and going to the deepest one where the event occurred.

               | |
---------------| |---------------
| div          | |              |
|   -----------| |-----------   |
|   | button   \ /          |   |
|   -------------------------   |
|        Event CAPTURING        |

Along the way, the handlers that were bound to this stage will be executed at the capturing stage. The binding is regulated by the third parameter of the addEventListener function.

button.addEventListener('click', () => alert('Boom 1!'), true);
div.addEventListener('click', () => alert('Boom 2!'), true);

The value true binds handlers to the capturing stage. The following output will result:

Boom 2!
Boom 1!


Once the capturing stage ends at the target element, the bubbling stage begins.

               / \
---------------| |---------------
| div          | |              |
|   -----------| |-----------   |
|   | button   | |          |   |
|   -------------------------   |
|        Event BUBBLING         |

It's this stage that's implied when calling addEventListener without specifying the third parameter.

button.addEventListener('click', () => alert('Boom 1!'));
div.addEventListener('click', () => alert('Boom 2!'));

At this stage, the handlers are executed from the inside out:

Boom 1!
Boom 2!


Event bubbling is an important part of DOM behavior. Without it, it would be impossible to implement events that are triggered on entire blocks, not just the deepest elements. The simplest example is a context menu. Another example could be tables arranged like in Microsoft Excel. These tables are huge, and adding events to each cell would create a large number of identical handlers that need to be constantly added as the table grows. Besides the extra code, this strategy slows everything down if you're working with a lot of things. It's much easier to put one handler on the whole table.

W3C Model

According to the standard, most events go through both stages, first plunging into the depths of the tree and then rising to the very top. The dive stage is rarely used, most of the handlers are hung on the ascent stage.

In the previous lesson, we saw the object. This is the deepest element that the capture stage goes to. Target doesn't change during bubbling. It allows you to always find out exactly where the event took place. In addition, the currentTarget bject is also available; this is the element the handler is attached to. One or the other is used, depending on the situation.

Event Stages

In a normal situation, the event should bubble to the end, but there are some situations where bubbling is undesirable.

There are two ways to do this:

  • event.stopPropagation() - stops the popup, but gives all the handlers that are hovering over the current element a chance to refine,
  • event.stopImmediatePropagation() - doesn't allow any more handlers to be executed

Let's summarize. Interception is a mechanism for passing an event to a handler. During capturing or bubbling, the event passes from one element to another, and if there is a handler for this event in the element, it gets called, in other words, the event is intercepted by the handler. And using by using the methods described above, we can stop the process of passing an event between elements.

Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
hours of theory

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing:">Bookmate</span>
<span class="translation_missing" title="translation missing:">Healthsamurai</span>
<span class="translation_missing" title="translation missing:">Dualboot</span>
<span class="translation_missing" title="translation missing:">Abbyy</span>
Suggested learning programs

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.