Introduction
Javascript events happen in three phases, namely,
1.the capturing phase,
2.the target phase and
3.the bubbling phase.
Before understanding how event propagation works, let's understand why we have to understand event propagation.
Sometimes, JavaScript event handlers may get invoked in unintended places. If we understand how event propagation occurs, we can avoid those kind of unintended event handling.
Consider the following example:
<div id="main-section">
<button id="main-btn">click me</button>
</div>
const mainSection = document.getElementById("main-section");
const mainButton = document.getElementById("main-btn");
mainSection.addEventListener("click", () => {
console.log("Clicked main-section");
});
mainButton.addEventListener("click", () => {
console.log("Clikced button");
});
We have a div element with id main-section
, inside which we have a button with id main-btn
.
We are adding a click event listener to the div, which will print the string Clicked main-section
to the console. Similarly, we have a click event listener for the button as well, which will print the string Clikced button
to the console.
Let's say we click the button, what will get printed on the console?
If you guessed Clikced button
, you are wrong. It will print both Clikced button
and Clicked main-section
.
The event handler of button is invoked first and then the event handler of div is invoked.
The three phases
Let's understand why. The event is not generated at the target element, where the event happened. Instead the event is generated at the root of the document (i.e, the top of the DOM tree)
Then the event travels downwards, from the root to the target element. This phase is called the capturing phase. As it travels down, the event will be passed through every single parent of the target element.
As soon as the event reaches the target, the event listener attached to the target element will start executing. This phase is called as the target phase.
Once target phase is over, the event will travel all the way up to the root again, this phase is called as the bubbling phase. In bubbling phase,similar to capturing phase, the event will be passed through all the parents.
We can notice that, in case of both capturing phase and bubbling phase, events are passed through the parents. It's like the event has happened in all these parent elements. Which means, if you have an event listener of same kind in one of the parent elements, that event listener will also be executed while performing the event on the target.
By default, events can be handled in the target element, during the bubbling phase. This explains why the event handler of div is invoked after the event handler of the button.
During the capturing phase, the event will travel from the root to the button and the target phase will take place, during which the event handler of the button will get invoked and Clikced button
will get printed to the console. And finally during the bubbling phase, the event will travel from the target to the root, through the button's parents. Since we have a click event listener on the main-section div, it will be invoked and the string Clicked main-section
will get printed to the console.
Event bubbling prevention
Inorder to prevent the propagation of the event, you can invoke the stopPropagation
method of the event. If you invoke this method, the event propagation will stop then and there in the target itself, it will not travel up to the root. In other words, the bubbling phase will not take place.
mainButton.addEventListener("click", (event) => {
console.log("Clikced button");
event.stopPropagation();
});
Top comments (0)