Compile Ready
Module 12 · Browser APIs

Event Bubbling

Intermediate9m read7m practice16m total
EventsBubblingPropagationUI

Introduction

Event bubbling is the phase where an event starts at the target and then travels upward through ancestors. A click on a button can be observed by the button, its card, its list, and higher containers.

This is why one user action can trigger multiple handlers. It is also the foundation for event delegation.

Why This Matters

Bubbling explains common interview snippets: a child click logs before a parent click, stopPropagation changes the order, and a parent can handle clicks for many children. Without this mental model, event bugs look random.

Theory

What bubbles?

Many common events bubble: click, input, change, keydown, and most pointer events. Some events do not bubble or have bubbling alternatives. For example, focus and blur do not bubble, while focusin and focusout do.

Bubble order

For a nested target, the bubble phase runs from the target upward: target, parent, grandparent, and so on. During that journey, event.target stays the original source while event.currentTarget changes for each listener.

Stopping bubbling

Use event.stopPropagation() sparingly. It can be appropriate for nested controls, modals, and menus, but overusing it makes components hard to compose because outer code can no longer observe legitimate events.

Bubbling vs default action

Bubbling is about listener order. It is not the same as default behavior. Calling stopPropagation on a link click does not stop navigation; call preventDefault for that.

Visual Diagrams

Capture to target to bubble
root
  |
  v  capture phase
section
  |
  v
button  target phase
  |
  ^
section
  |
  ^  bubble phase
root

Bubbling is the upward half of the event journey, from the target back through ancestors.

Bubbling order for a button click
button listener
  then
card listener
  then
list listener
  then
page listener

The deepest target handles the bubble phase before its ancestors.

Code Examples

Observe bubbling through nested elements

All three listeners can see the same click. currentTarget changes at each step.

Loading…

Stop a nested click from reaching ancestors

Use this carefully because it prevents outer components from seeing the event.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1const pathFromTarget = ['button', 'card', 'root'];
2let stopped = false;
3
4for (const name of pathFromTarget) {
5 if (stopped) {
6 continue;
7 }
8
9 console.log(name);
10
11 if (name === 'card') {
12 stopped = true;
13 }
14}

Coding Exercises

Return the bubbling path

Easy

Implement getBubbleOrder(target, parentMap) where parentMap maps a node name to its parent name. Return an array from target to root.

Interview Questions

1What is event bubbling?

Event bubbling is the propagation phase where an event travels from its target up through ancestor nodes. A click on a button can trigger the button listener first, then parent listeners, unless propagation is stopped.

Asked at:GoogleMicrosoftAmazon

Follow-ups

  • How does bubbling enable event delegation?
2Does `stopPropagation` prevent a link from navigating?

No. stopPropagation stops the event from moving to later ancestors. Link navigation is the default action, so it requires preventDefault on a cancelable click event.

Asked at:MetaNetflix

Quiz

1. During bubbling, which listener usually runs first for a click inside nested elements?

2. Which method stops the event from reaching later ancestors?

Summary

  • Bubbling moves from the event target upward through ancestors.
  • `target` stays the original source; `currentTarget` changes as listeners run.
  • `stopPropagation` stops later ancestors but does not cancel default action.
  • Bubbling is the mechanism that makes event delegation practical.

Cheat Sheet

Bubble path: target → parent → grandparent → root.

Common bubbling events: click, input, change, keydown, pointer events.

Non-bubbling examples: focus, blur (use focusin, focusout when delegation is needed).

Stop: event.stopPropagation().

Remember: stopping propagation is not the same as preventing default action.