Skip to content

JavaScript Tutorial Events

JavaScript Event Bubbling and Capturing

Lesson 118 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

When you click a button inside a card inside a page, you really clicked all three of them. The browser reports the event to each one, from the inside out. That is bubbling, named after bubbles rising in water.

index.html
HTML
<div id="card" style="padding:14px;background:#fdf2e9">
  Card
  <button id="btn">Button</button>
</div>
<script>
  document.querySelector("#btn").addEventListener("click", () => console.log("1. button"));
  document.querySelector("#card").addEventListener("click", () => console.log("2. card"));
  document.addEventListener("click", () => console.log("3. document"));
</script>

Click the button. The console shows 1. button, then 2. card, then 3. document.

The three phases

Every event goes through:

  1. Capturing: from window down to the target.
  2. Target: at the element itself.
  3. Bubbling: from the target back up to window.

By default, listeners run in the bubbling phase. To listen while the event is going down, pass true or { capture: true }:

script.js
JS
card.addEventListener("click", handler, { capture: true });

You will rarely need capturing. Know that it exists.

Bubbling is useful

Because events rise, a listener on a parent can handle events from all its children. That is event delegation, covered next: Event Delegation.

Controlling it

event.stopPropagation() stops the event from going further, as shown in preventDefault and stopPropagation. Prefer to leave events alone unless there is a reason.

Events that do not bubble

A few events do not bubble: focus, blur, mouseenter, mouseleave, load. For delegation, use their bubbling cousins focusin, focusout, mouseover and mouseout.

Which element handled it?

Use event.target for the innermost element that was clicked and event.currentTarget for the element whose listener is running: The Event Object.

A common problem: nested handlers

If both a card and a button inside it have click handlers, clicking the button runs both. Decide which one should run, check event.target in the outer handler, or restructure the code so the layers do not overlap.

info
Remember the order
Bubbling goes inside out: target first, then each parent. Capturing goes outside in.