Why Does Event Bubbling Happen by Default? (And Why It Makes Sense)

Why Does Event Bubbling Happen by Default? (And Why It Makes Sense) When studying event bubbling, you might wonder: Why does it happen by default? Why do we need to explicitly call stopPropagation() to prevent it?. If you are not clear on what event bubbling is, check out my previous aritcle. The short answer is: it’s intentional and very important. Let’s break down the reasons why event bubbling is enabled by default in the browser. Consistent Event Handling Behavior in Parent Elements It is the core reason of event bubbling happen by default. Take a look at the following example: Card Heading Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis doloremque harum repellat nesciunt! Mollitia repellat accusamus, distinctio in dolor aperiam! Button const card = document.querySelector(".card"); card.addEventListener("click", (e) => { alert("Card clicked ========="); }); Without Bubbling? In this example, we have a card component with children: a heading, paragraph, button, and an image inside a div. What do we usually expect? That clicking anywhere on the card — whether on the text, image, or button — will trigger the card’s click event, right? Yes it is because of the bubbling. Because clicking of any of the children propagate into parent. If bubbling didn’t happen by default, then clicking on the image, button, or heading wouldn’t trigger the card’s click event — and that would create a bad UX in many situations. Let's simulate it. const card = document.querySelector(".card"); const cardHeading = document.querySelector(".card h3"); const cardParagraph = document.querySelector(".card p"); const cardButton = document.querySelector(".card button"); const cardDiv = document.querySelector(".card div"); card.addEventListener("click", (e) => { alert("Card clicked ========="); }); /* these is for simulating for if even bubbling for click no happen by default*/ cardHeading.addEventListener("click", (e) => { e.stopPropagation(); }); cardDiv.addEventListener("click", (e) => { e.stopPropagation(); }); cardParagraph.addEventListener("click", (e) => { e.stopPropagation(); }); cardButton.addEventListener("click", (e) => { e.stopPropagation(); }); Here I simulated all children of card click event bubbling prevented. If it happen by default then it feels like: So then to trigger children of card we explicitly have to target all children and one by one enable bubbling. And not in one place rather most of the place where we need that feature. Imagine a card with 20 child elements. Without bubbling, you’d have to attach individual click handlers to each of them just to simulate a single action — sounds like a nightmare, right? So, to allow a feature where clicking anywhere on the card triggers an action, you’d have to manually enable event propagation for each child — one by one. Hypothetically assuming event have a method name event.enablePropagation() (that enable propagation or bubbling), then code will be look like following. const card = document.querySelector(".card"); const cardHeading = document.querySelector(".card h3"); const cardParagraph = document.querySelector(".card p"); const cardButton = document.querySelector(".card button"); const cardDiv = document.querySelector(".card div"); card.addEventListener("click", (e) => { alert("Card clicked ========="); }); /* these is for simulating for if even bubbling for click no happen by default */ cardHeading.addEventListener("click", (e) => { event.enablePropagation(); // it doesn't exist in javascript, assuming hypothetically }); cardDiv.addEventListener("click", (e) => { event.enablePropagation(); }); cardParagraph.addEventListener("click", (e) => { event.enablePropagation(); }); cardButton.addEventListener("click", (e) => { event.enablePropagation(); }); Or second way is we have to copy and past same event in every child if we want to find second possible way. const card = document.querySelector(".card"); const cardHeading = document.querySelector(".card h3"); const cardParagraph = document.querySelector(".card p"); const cardButton = document.querySelector(".card button"); const cardDiv = document.querySelector(".card div"); card.addEventListener("click", (e) => { alert("Card clicked ========="); /* other code ====== */ }); /* these is for simulating for if even bubbling for click no happen by default */ cardHeading.addEventListener("click", (e) => { alert("Card clicked ========="); /* other code ====== */ }); cardDiv.addEventListener("click", (e) => { alert("Card clicked ========="); /* other code ====== */ }); cardParagraph.addEventListener("click", (e) => { alert("Card clicked ========="); /* other code ====== */ }); cardButton.addEventListener("click", (e) => { alert("Card cl

Apr 20, 2025 - 04:26
 0
Why Does Event Bubbling Happen by Default? (And Why It Makes Sense)

Why Does Event Bubbling Happen by Default? (And Why It Makes Sense)

When studying event bubbling, you might wonder: Why does it happen by default? Why do we need to explicitly call stopPropagation() to prevent it?.
If you are not clear on what event bubbling is, check out my previous aritcle.

The short answer is: it’s intentional and very important.

Let’s break down the reasons why event bubbling is enabled by default in the browser.

Consistent Event Handling Behavior in Parent Elements

It is the core reason of event bubbling happen by default.

Take a look at the following example:


   class="card">
    

Card Heading

class="card-img"> src="water-ripple.jpg" alt="" />

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis doloremque harum repellat nesciunt! Mollitia repellat accusamus, distinctio in dolor aperiam!