Skip to main content
  1. Posts/

What Happens When You Click a Button? Exploring Event Bubbling in JavaScript

·2 mins
Web Development JavaScript Dom Javascript Html
Table of Contents

In a complex web page, we often attach different event listeners to nested elements. Take the following HTML as an example:

<div id="parent">
  <button id="child">Click me</button>
</div>

Now, suppose we attach click event listeners to both the div and the button:

document.getElementById("parent").addEventListener("click", () => {
  console.log("Parent clicked");
});

document.getElementById("child").addEventListener("click", () => {
  console.log("Child clicked");
});

So, which event listener will be triggered first when we click the button?

Event Bubbling
#

To answer that, we need to introduce a mechanism in JavaScript called Event Bubbling. Event bubbling means that when an event is triggered on a nested element, it starts from the innermost target and then propagates upward through the DOM tree. Along the way, all ancestor elements with listeners for the same event will be triggered, one by one—just like a bubble rising from the bottom of the water.

In the example above, when we click the button, the event is first handled by the child element, then it bubbles up to the parent, and continues up to document.body, document, and even window.

Given this mechanism, the output of the code above will be:

Child clicked
Parent clicked

How to Stop the Bubbling Process
#

Sometimes, we might not want the event to bubble up—perhaps we only want the current element to handle the event, without triggering any listeners on parent elements. In such cases, you can use:

event.stopPropagation();

This line stops the event from continuing to propagate upward. For example:

document.getElementById("child").addEventListener("click", (event) => {
  event.stopPropagation();
  console.log("Child clicked");
});

Now, even if we click the button, the output will be:

Child clicked

Practical Example: Event Delegation
#

Event bubbling is not just a behavior—it also enables a powerful technique called event delegation.

Imagine you have a list where each item needs to respond to clicks:

<ul id="list">
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
</ul>

A traditional approach would be to bind an event listener to each li element. But this is inefficient, and you’ll need extra logic to handle dynamically added items.

Thanks to event bubbling, you can attach just one event listener to the ul element and determine which li was clicked by inspecting event.target:

document.getElementById("list").addEventListener("click", (event) => {
  if (event.target.tagName === "LI") {
    console.log(`You have clicked: ${event.target.textContent}`);
  }
});

This is called event delegation. It makes your code cleaner, more efficient, and easier to maintain—especially when dealing with dynamic content.

Related

Differences Between Element Node, Text Node, and Comment Node
·1 min
Web Development JavaScript Dom Javascript Html Css
Difference Between Static and Live Collections
·2 mins
Web Development JavaScript Dom Javascript Html Css
Node Types in the DOM and the Document Object
·1 min
Web Development JavaScript Dom Javascript Html Css