DEV Community

Cover image for The DOM Bubble! What is event bubbling, and how to handle it?
Abdus Shohid Shakil
Abdus Shohid Shakil

Posted on • Edited on

The DOM Bubble! What is event bubbling, and how to handle it?

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.

Event bubbling with bubble example

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.

Event bubbling with water ripple example

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.

Event bubbling with practical example

<body>
  <div class="container">
    <div class="card">
      <button>Button</button>
    </div>
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode

For this html document dom tree will something like:

dom tree example

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.

bubbling event through dom tree

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");
});
Enter fullscreen mode Exit fullscreen mode

If you click the button, the sequence will be:

- "button click"
- "Card click"
- "container click"
- "body click"
Enter fullscreen mode Exit fullscreen mode

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.

event example with bubbling

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
});
Enter fullscreen mode Exit fullscreen mode

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");
});
Enter fullscreen mode Exit fullscreen mode

after preventing bubbling

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");
});
Enter fullscreen mode Exit fullscreen mode

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)

Here's my LinkedIn profile

Thank you

Top comments (0)