Hiprup

What is event bubbling and capturing?

When an event fires, it travels through the DOM in two phases.

  • Capturing phase — the event travels top-down, from the root down to the target element.

  • Bubbling phase — the event travels bottom-up, from the target back up to the root.

By default, listeners fire during the bubbling phase. To listen during capturing, pass true (or { capture: true }) as the third argument to addEventListener.

Good to know: stop the journey with event.stopPropagation(); bubbling is also what makes event delegation possible.

// HTML: <div id="outer"><div id="inner"><button>Click</button></div></div>

// Bubbling (default) — bottom-up
document.getElementById('outer').addEventListener('click', () => {
  console.log('Outer clicked');  // Fires second (bubbling up)
});
document.getElementById('inner').addEventListener('click', () => {
  console.log('Inner clicked');  // Fires first (closer to target)
});
// Click button: 'Inner clicked', 'Outer clicked'

// Capturing — top-down
document.getElementById('outer').addEventListener('click', () => {
  console.log('Outer (capture)');  // Fires first (capturing down)
}, { capture: true });
document.getElementById('inner').addEventListener('click', () => {
  console.log('Inner (capture)');  // Fires second
}, { capture: true });
// Click button: 'Outer (capture)', 'Inner (capture)'

// Stop propagation
document.getElementById('inner').addEventListener('click', (e) => {
  e.stopPropagation();  // Outer handler will NOT fire
  console.log('Inner only');
});

// Event delegation uses bubbling
document.getElementById('list').addEventListener('click', (e) => {
  if (e.target.matches('.delete-btn')) {
    deleteItem(e.target.closest('li').dataset.id);
  }
});

Bubbling: inner fires first, then outer (bottom-up). Capturing: outer fires first, then inner (top-down, needs {capture: true}). stopPropagation prevents the event from reaching outer.

Event delegation leverages bubbling — one listener on a parent handles all child clicks.

Know the three phases: capturing (down) → target → bubbling (up). Default is bubbling. stopPropagation stops travel.

Event delegation uses bubbling (one parent listener for many children). Capturing is rarely used but asked about.

What is event bubbling and capturing? | Hiprup