Skip to main content

Command Palette

Search for a command to run...

Understanding Event Phases in JavaScript: Capturing, Target, and Bubbling

Updated
3 min read

Handling events is a core part of building interactive web applications. Whenever a user clicks a button, submits a form, or presses a key, the browser generates an event.

What many developers don’t realize at first is that events don’t just occur on a single element—they travel through the DOM in a structured process called event propagation.


What is Event Propagation?

Event propagation defines how an event moves through the DOM tree. This movement follows a sequence known as the event flow.

The event flow consists of three phases:

  • Capturing Phase

  • Target Phase

  • Bubbling Phase

Understanding these phases helps you write more predictable and efficient event-handling logic.


1. Capturing Phase

The capturing phase is the first stage of event propagation.

In this phase, the event starts from the top of the DOM tree and travels downward toward the target element.

Flow: Document → HTML → Body → Parent → Target

Example:

document.getElementById("parent").addEventListener(
  "click",
  () => {
    console.log("Parent clicked during capturing phase");
  },
  true
);

Passing true as the third argument enables capturing.

Key Point:

Capturing is useful when you want parent elements to handle an event before it reaches the target element.


2. Target Phase

The target phase occurs when the event reaches the element that triggered it.

For example, if a button inside a <div> is clicked, the button becomes the target.

Example:

document.getElementById("button").addEventListener("click", () => {
  console.log("Button clicked");
});

Key Point:

This is the actual point of interaction where the event originates.

3. Bubbling Phase

After the target phase, the event enters the bubbling phase.

In this phase, the event travels upward through the DOM tree back toward the root.

Flow:

Target → Parent → Body → HTML → Document

Example:

document.getElementById("parent").addEventListener("click", () => {
  console.log("Parent clicked during bubbling phase");
});

Key Point:

  • Bubbling is the default behavior

  • Commonly used for event delegation


Visualizing Event Flow

Consider this DOM structure:

Document
 └── HTML
      └── Body
           └── Parent Div
                └── Button

When the button is clicked:

Capturing Phase:

Document → HTML → Body → Parent → Button

Target Phase:

Button

Bubbling Phase:

Button → Parent → Body → HTML → Document

Example: Capturing + Bubbling Together

parent.addEventListener(
  "click",
  () => {
    console.log("Parent capturing");
  },
  true
);

button.addEventListener("click", () => {
  console.log("Button clicked");
});

parent.addEventListener("click", () => {
  console.log("Parent bubbling");
});

Output:

Parent capturing
Button clicked
Parent bubbling

This shows that:

  • Capturing happens before the event reaches the target

  • Bubbling happens after the target


Capturing vs Bubbling

Capturing Phase:

  • Moves top → down

  • Enabled using true

  • Less commonly used

  • Useful for early interception

Bubbling Phase:

  • Moves bottom → up

  • Default behavior

  • Widely used

  • Enables event delegation


Conclusion

Event propagation is fundamental to how browsers handle user interactions. Every event passes through three stages: capturing, target, and bubbling.

By understanding and controlling these phases using addEventListener(), you can build more efficient and scalable applications.

Mastering this concept is a key step toward becoming proficient in JavaScript DOM manipulation.

4 views