The conecpt:
Event bubbling is a concept in javascript dom where an event propagetes to its parents elements.
The concept of bubbling is similar to how a real bubble works.
How does a bubble works?
Think about a bubble -- it floats up in the air, right? But it doesn't stay up forever. Eventually, it props! It starts samll and grows bigger as it rises.
Still confused? No worries! Imagine throwing a stone into a pond. The water ripples out from where the stone hit, right? It keeps going until it fades away. In similar way when a click or any other bubbling event trigger it spreads out from the targeted element up-to parents and that's parents until it reaches the root element.
With real example:
Now let's understand by an real example.
<body>
<div class="container">
<div class="card">
<button>Button</button>
</div>
</div>
</body>
For this html document dom tree will something like:
What happens when the button is clicked?
Clicking on the button first button
will trigger the event and that bubble(event) upto its parent card
element and then container
and finally the body
element and as body is the root so it will stop bubbling.
It will be more clear if we add event listener.
const body = document.querySelector("body");
const container = document.querySelector(".container");
const card = document.querySelector(".card");
const button = document.querySelector(".card button");
body.addEventListener("click", (e) => {
alert("body click");
});
container.addEventListener("click", (e) => {
alert("container click");
});
card.addEventListener("click", (e) => {
alert("Card click");
});
button.addEventListener("click", (e) => {
alert("button click");
});
If you click the button, the sequence will be:
- "button click"
- "Card click"
- "container click"
- "body click"
Here if user click on the button it will first tigger button listener and alert button click
and then even will pass to its parent card element and alert Card click
and then its parent container and alert container click
and lastly body and alert body click
as these all element have event listener for click event so all of it's parents will be trigger, which you may not want.
So now we understand what actaully event bubbling is. Now question is how to prevent it?
Before we stop bubbling, let’s understand that not all events bubble. You can check if an event bubbles like this:
button.addEventListener("click", (e) => {
event.bubbles; // true if event is bubbling else false
});
Here is a list of bubbling and non-bubbling events
🫧 Bubbling Events:
click
dblclick
mousedown
keydown
change
select
- ...and many more
🚫 Non-Bubbling Events:
focus
blur
submit
reset
mouseenter
mouseleave
- ...and many more
How to prevent that propagation?
To stop the event from bubbling, simply call event.stopPropagation()
.
For example, if we use stop propagtion only in button:
body.addEventListener("click", (e) => {
alert("body click");
});
container.addEventListener("click", (e) => {
alert("container click");
});
card.addEventListener("click", (e) => {
alert("Card click");
});
button.addEventListener("click", (e) => {
e.stopPropagation();
alert("button click");
});
it will solve the propagation of click event for button but when click in card it will still propagate to its parent container so if we also don't want that for all then just use stopPropagation
body.addEventListener("click", (e) => {
e.stopPropagation();
alert("body click");
});
container.addEventListener("click", (e) => {
e.stopPropagation();
alert("container click");
});
card.addEventListener("click", (e) => {
e.stopPropagation();
alert("Card click");
});
button.addEventListener("click", (e) => {
e.stopPropagation();
alert("button click");
});
Conclusion:
In summary, event bubbling is the default behavior in JavaScript where an event propagates from the targeted DOM element to the root element. This can be useful in many situations, but if you want to stop it, you can use event.stopPropagation()
.
If this helped you understand the concept, feel free to share, follow, or ask me about any topic you'd like me to cover next!
You can also read: Why Does Event Bubbling Happen by Default? (And Why It Makes Sense)