What is Event Propagation?
Event Propagation determines in which order the elements receive the event. When we click on a nested element, the event doesn’t just fire on that element — it travels through the entire DOM tree in three phases:
- Capturing Phase — the event goes from the top (
window) down to the target element (parent to child) - Target Phase — the event reaches the actual element that was clicked
- Bubbling Phase — the event goes back up from the target to the top (child to parent)
In simple language, when we click on something, the event first goes down the DOM tree, hits the target, and then comes back up. Most of the time we only care about the bubbling phase (which is the default behavior).
↓
↓
↓
body
div
p
a
← click target
↑
↑
↑
Event Bubbling
The bubbling principle is simple. When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.
Let’s say we have 3 nested elements FORM > DIV > P with a handler on each of them:
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
When clicking on <p> it will show alert() for p, then it will fire event of its parent that is <div> and so on.
To stop it, event.stopPropagation() is used:
<body onclick="alert(`the bubbling doesn't reach here`)">
<button onclick="event.stopPropagation()">Click me</button>
</body>
Event Capturing
Reverse of bubbling. Events fire from parent to child.
document.getElementById("el").addEventListener(
"click",
() => {},
true // <-- This enables capturing mode
);