JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsjavascript
PrevNext

Learn the concept

Events

javascript
mid
events

Explain event bubbling, capturing, and how stopPropagation works.

events
bubbling
capturing
propagation
dom
event-delegation
Quick Answer

Events propagate through the DOM in three phases: capturing (top-down), target, and bubbling (bottom-up). stopPropagation() prevents the event from continuing to the next phase, while stopImmediatePropagation() also blocks remaining handlers on the current element.

Detailed Explanation

When a DOM event fires, it doesn't just trigger on the target element — it travels through the entire DOM tree in a defined order called event propagation. Understanding these phases is essential for event delegation, handling complex UIs, and debugging unexpected behavior.

The Three Phases

  1. Capturing phase (top-down): The event travels from window down through the DOM tree toward the target element. Handlers registered with { capture: true } or true as the third argument to addEventListener fire during this phase.

  2. Target phase: The event reaches the element that triggered it. Both capture and bubble handlers on the target element fire during this phase, in the order they were registered.

  3. Bubbling phase (bottom-up): The event travels back up from the target to window. This is the default — handlers registered without capture: true fire during this phase.

Most events bubble, but some do not: focus, blur, mouseenter, mouseleave, load, scroll, and resize do not bubble. Use focusin/focusout as bubbling alternatives to focus/blur.

event.target vs event.currentTarget

  • event.target — the element that actually triggered the event (e.g., the button that was clicked)
  • event.currentTarget — the element the handler is attached to (e.g., the parent <div> listening via delegation)

These are the same only when the handler is on the target element itself. In event delegation patterns, they differ.

stopPropagation vs stopImmediatePropagation

  • event.stopPropagation() — stops the event from continuing to the next phase (no more capturing down or bubbling up), but other handlers on the same element still fire.
  • event.stopImmediatePropagation() — stops propagation AND prevents any remaining handlers on the same element from executing.

Neither affects preventDefault() — stopping propagation does not cancel the browser's default action.

preventDefault vs stopPropagation

  • event.preventDefault() — cancels the browser's default action (form submit, link navigation) but the event still propagates.
  • event.stopPropagation() — stops the event from reaching other elements but the default action still happens.

To do both, call both methods.

Practical Example: Event Delegation

Event delegation leverages bubbling — attach one listener to a parent instead of many listeners to children:

JavaScript
ul.addEventListener('click', (e) => {
  if (e.target.matches('li')) {
    handleItemClick(e.target);
  }
});

This works because clicks on <li> elements bubble up to the <ul>. It also handles dynamically added items automatically.

Code Examples

Demonstrating Propagation PhasesJavaScript
// HTML: <div id="outer"><div id="inner"><button id="btn">Click</button></div></div>

const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');

// Capture phase (top-down)
outer.addEventListener('click', () => console.log('outer capture'), true);
inner.addEventListener('click', () => console.log('inner capture'), true);

// Bubble phase (bottom-up) — default
btn.addEventListener('click', () => console.log('button target'));
inner.addEventListener('click', () => console.log('inner bubble'));
outer.addEventListener('click', () => console.log('outer bubble'));

// Clicking the button logs:
// 1. "outer capture"  (capture, top-down)
// 2. "inner capture"  (capture, continues down)
// 3. "button target"  (target phase)
// 4. "inner bubble"   (bubble, bottom-up)
// 5. "outer bubble"   (bubble, continues up)

Real-World Applications

Use Cases

Dropdown Menus

Close dropdown menus by listening for clicks on the document body. Use stopPropagation on the dropdown itself to prevent clicks inside it from triggering the close handler.

Modal Overlays

Close modals when clicking the overlay background but not when clicking inside the modal content, using event.target comparison or stopPropagation.

Mini Projects

Event Propagation Visualizer

intermediate

Build a nested DOM structure where clicking any element highlights the propagation path in real-time, showing capture → target → bubble phases with timing.

Industry Examples

React

React's synthetic event system delegates all events to the root container using bubbling, then dispatches to the correct component handlers internally for performance.

Resources

MDN - Event Bubbling

docs

JavaScript.info - Bubbling and Capturing

article

Related Questions

What is event delegation in JavaScript and why is it useful?

junior
events

How do you select and manipulate DOM elements in JavaScript?

junior
dom
Previous
What are WeakMap and WeakSet, and how do they differ from Map and Set?
Next
How do you implement data polling in JavaScript?
PrevNext