JavaScript Event Propagation
Event propagation defines the order in which events travel through the DOM (Document Object Model) when an event is triggered. It determines how and when event handlers are executed on nested elements.
When an event (like a click) happens on a DOM element, it doesn’t just stay there — it travels through three phases:
1. Capturing Phase (Event Capture)
- The event starts from the root (
window
/document
) and travels down to the target element. - If a handler is set to capture mode, it will be triggered before the event reaches the target.
document.getElementById("outer").addEventListener("click", () => {
console.log("Outer (Capturing)");
}, true); // true = capture phase
2. Target Phase
- The event reaches the target element (the actual element clicked or interacted with).
- If that element has an event listener, it executes here.
document.getElementById("button").addEventListener("click", () => {
console.log("Button (Target Phase)");
});
3. Bubbling Phase (Event Bubble)
- After reaching the target, the event bubbles up from the target element back through its ancestors (parent, grandparent, etc.).
- This is the default behavior for most events.
document.getElementById("outer").addEventListener("click", () => {
console.log("Outer (Bubbling)");
}); // default is false = bubbling phase
Example of Event Propagation
HTML:
<div id="outer">
<button id="inner">Click Me</button>
</div>
JavaScript:
document.getElementById("outer").addEventListener("click", () => {
console.log("Outer DIV");
});
document.getElementById("inner").addEventListener("click", () => {
console.log("Inner BUTTON");
});
Stopping Propagation
You can stop the event from moving further up or down the DOM tree.
a) stopPropagation()
Stops the event from continuing in either direction (up or down).
inner.addEventListener("click", (e) => {
e.stopPropagation();
console.log("Inner only!");
});
b) stopImmediatePropagation()
Stops propagation and prevents other handlers on the same element from executing.
inner.addEventListener("click", (e) => {
e.stopImmediatePropagation();
console.log("This runs, others won’t.");
});
preventDefault()
Stops the default action of an element (e.g., link navigation, form submission).
document.querySelector("a").addEventListener("click", (e) => {
e.preventDefault();
console.log("Link click prevented");
});