Event Propagation and Delegation in JavaScript

JavaScript events follow a structured flow within the DOM, known as event propagation, which includes two main phases: capturing and bubbling. Event delegation leverages this flow to efficiently handle events on multiple child elements using a single event listener on a parent.

1. Event Propagation

1.1. Capturing Phase

  • The event travels from the root of the DOM tree down to the target element.
  • Also known as the “trickle-down phase.”
  • Event listeners in this phase execute if useCapture is set to true when adding the listener.

Example:

document.body.addEventListener(

  “click”,

  () => console.log(“Capturing phase”),

  true

);

1.2. Target Phase

  • The event reaches the target element, where event listeners on the target execute.

1.3. Bubbling Phase

  • The event bubbles back up the DOM tree, starting from the target to the root.
  • Event listeners execute by default during this phase.

Example:

document.body.addEventListener(“click”, () => console.log(“Bubbling phase”));

2. Stopping Event Propagation

2.1. event.stopPropagation()

  • Prevents the event from propagating further in either the capturing or bubbling phase.

Example:

document.querySelector(“#child”).addEventListener(“click”, (event) => {

  event.stopPropagation();

  console.log(“Child clicked, propagation stopped!”);

});

2.2. event.stopImmediatePropagation()

  • Prevents the event from propagating and blocks other listeners on the same element.

3. Event Delegation

Event delegation leverages event propagation (bubbling phase) to handle events for multiple child elements by attaching a single event listener to their parent.

Example:

document.querySelector(“#list”).addEventListener(“click”, (event) => {

  if (event.target.tagName === “LI”) {

    console.log(`Item clicked: ${event.target.textContent}`);

  }

});

4. Key Differences: Capturing vs Bubbling

PhaseExecutionDefault Behavior
Capturing PhaseRoot → TargetRequires useCapture: true
Bubbling PhaseTarget → RootDefault for most events

Multiple-Choice Questions

What is the correct order of phases in event propagation?

  1. Capturing → Target → Bubbling
  2. Bubbling → Target → Capturing
  3. Target → Capturing → Bubbling
  4. Capturing → Bubbling → Target

Answer: 1. Capturing → Target → Bubbling
Explanation: Event propagation starts with the capturing phase, reaches the target, and then proceeds with the bubbling phase.

What is the default phase for most event listeners?

  1. Capturing
  2. Bubbling
  3. Target
  4. None

Answer: 2. Bubbling
Explanation: By default, event listeners execute during the bubbling phase.

What does the event.stopPropagation() method do?

  1. Stops the event from reaching the target element.
  2. Prevents the event from propagating in the bubbling phase.
  3. Stops all listeners from executing on the target element.
  4. Cancels the default action of the event.

Answer: 2. Prevents the event from propagating in the bubbling phase.
Explanation: stopPropagation() prevents the event from continuing to propagate through the DOM hierarchy.

Which method prevents an event from propagating and blocks other listeners on the same element?

  1. event.preventDefault()
  2. event.stopPropagation()
  3. event.stopImmediatePropagation()
  4. event.cancel()

Answer: 3. event.stopImmediatePropagation()
Explanation: This method stops the event from propagating and prevents other event listeners on the same element from executing.

Which of the following best describes event delegation?

  1. Attaching listeners to multiple elements individually.
  2. Adding a single listener to a parent element to handle events for its child elements.
  3. Using stopPropagation to delegate events.
  4. Handling events during the capturing phase only.

Answer: 2. Adding a single listener to a parent element to handle events for its child elements.
Explanation: Event delegation relies on the bubbling phase to handle events for multiple child elements with a single parent listener.

What does this code do?

document.querySelector(“#parent”).addEventListener(“click”, (event) => {

  console.log(`Clicked: ${event.target.tagName}`);

});

  1. Logs the tag name of the parent element.
  2. Logs the tag name of the element that triggered the event.
  3. Prevents the event from bubbling.
  4. Throws an error.

Answer: 2. Logs the tag name of the element that triggered the event.
Explanation: The event.target property references the element that triggered the event.

Which property identifies the element where the event handler is attached?

  1. event.target
  2. event.currentTarget
  3. event.source
  4. event.handler

Answer: 2. event.currentTarget
Explanation: The currentTarget property refers to the element to which the event listener is attached.

What is the purpose of the useCapture parameter in addEventListener?

  1. Specifies the order of event listeners.
  2. Executes the listener during the capturing phase if true.
  3. Executes the listener during the bubbling phase if true.
  4. Stops the event propagation.

Answer: 2. Executes the listener during the capturing phase if true.
Explanation: The useCapture parameter determines if the listener executes during the capturing phase.

What does this code output when clicking the child element?

document.body.addEventListener(“click”, () => console.log(“Body clicked!”), true);

document.querySelector(“#child”).addEventListener(“click”, () => console.log(“Child clicked!”));

  1. Body clicked! → Child clicked!
  2. Child clicked! → Body clicked!
  3. Only Body clicked!
  4. Only Child clicked!

Answer: 1. Body clicked! → Child clicked!
Explanation: The useCapture: true causes the body listener to execute during the capturing phase, before the child listener.

What is a key advantage of event delegation?

  1. It prevents bubbling automatically.
  2. It requires fewer event listeners, improving performance.
  3. It works only during the capturing phase.
  4. It cancels the default action of the event.

Answer: 2. It requires fewer event listeners, improving performance.
Explanation: Event delegation minimizes the number of event listeners by attaching a single listener to a parent element.