JavaScript · The DOM

Event Bubbling

When you click a button, you also click everything around it. Events travel through the page in a predictable order.

Intermediate 5 min Lesson 28 of 49 Runnable examples
Before you start:Events
0/49 in JavaScript
On this page · 5 min · Intermediate

Learning objectives#

  • Describe the capture, target and bubble phases
  • Listen in the capture phase
  • Stop propagation when needed
  • Connect bubbling to event delegation

Explanation#

An event travels in three phases: capturing (from document down to the target), target, and bubbling (from the target back up to document).

Listeners run in the bubbling phase by default. Pass { capture: true } to run during capturing instead.

e.stopPropagation() stops the event travelling further. Use it rarely — it can break other code that relies on bubbling.

Bubbling is what makes event delegation possible: a parent hears events from all its children.

Code example: Watching an event travel#

HTMLWatching an event travel Runnable
<div id="outer" style="padding:20px;background:#e0e7ff">Outer
  <div id="inner" style="padding:20px;background:#c7d2fe">Inner
    <button id="btn">Click me</button>
  </div>
</div>


<script>
  for (const id of ['outer', 'inner', 'btn']) {
    document.getElementById(id).addEventListener('click', () => console.log('bubble:', id));
  }
  document.getElementById('outer').addEventListener('click', () => console.log('capture: outer'), { capture: true });
</script>
Expected output
(after clicking the button)
capture: outer
bubble: btn
bubble: inner
bubble: outer
Opens this example in the full playground

Step-by-step explanation#

  1. The capture listener on outer runs first, on the way down.
  2. The event reaches the button (target).
  3. It then bubbles up: inner, then outer.
  4. Clicking the inner box (not the button) would log capture: outer, bubble: inner, bubble: outer.

Real-world use case#

Closing a dropdown when clicking anywhere outside it, and handling clicks for a whole list with one listener.

Common mistakes#

Overusing stopPropagation

Stopping propagation can break analytics, menus and delegated handlers elsewhere on the page.

Assuming every event bubbles

focus and blur do not bubble; use focusin and focusout.

Best practices#

  • Rely on bubbling for delegation
  • Check e.target or closest() instead of stopping propagation
  • Use capture only when you must intercept early
  • Use focusin/focusout for delegated focus handling

Remember this#

Capture goes DOWN, bubble comes UP — like a diver.

Default listeners hear the bubble on the way up.

Bubbling is the superpower behind event delegation.

Practice exercise#

Your task: Add stopPropagation to the inner listener and predict what is logged when clicking the button.

Show solution
Text Illustrative
capture: outer
bubble: btn
bubble: inner
(outer’s bubble listener no longer runs)

Mini quiz#

Event Bubbling quizMultiple choice Question 1 of 1

In which phase do listeners run by default?

Score so far: 0/0

Want more? Practise all JavaScript MCQs · JavaScript interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.