When you click a button on a webpage, have you ever wondered how JavaScript knows which element to target first the button itself, its parent, or the entire document? This happens because of something called event propagation. And inside event propagation, two key concepts rule the game: event bubbling and event capturing.

If you’re learning JavaScript, understanding these two is a must. They explain how events travel through the DOM (Document Object Model) and how you can control them to build interactive, efficient applications. In this blog, we’ll simplify event bubbling and capturing with practical examples so you can actually apply them in your projects.
Before diving into bubbling and capturing, let’s talk about event propagation itself.
When you perform an action like clicking a button, the event doesn’t just stay there. It moves through different layers of the DOM from the root (document) down to the target element and back. This flow is called event propagation.
Propagation happens in three phases:
1. Capturing Phase → Event moves from the root down to the target element.
2. Target Phase → Event reaches the actual element you interacted with.
3. Bubbling Phase → Event moves back from the target element up to the root.
Now, let’s focus on the first and last — capturing and bubbling.
Event capturing means the event starts from the top (document/root) and trickles down to the target element. Think of it as water dripping from the top of a tree to its leaves.
By default, JavaScript doesn’t use capturing unless you explicitly enable it. You do that by passing a third parameter as true in addEventListener().
Example of Capturing
Copy Code
<!DOCTYPE html>
<html>
<head>
<title>Event Capturing</title>
</head>
<body>
<div id="parent">
<button id="child">Click Me</button>
</div>
<script>
document.getElementById("parent").addEventListener("click", function() {
console.log("Parent clicked");
}, true);
document.getElementById("child").addEventListener("click", function() {
console.log("Child clicked");
}, true);
</script>
</body>
</html>Output (when button is clicked):
Parent clicked
Child clicked
Here, the parent’s event listener runs first, because we used capturing.
Event bubbling is the opposite. The event starts at the target element and then “bubbles up” to its ancestors. This is JavaScript’s default behavior.
Example of Bubbling
Copy Code
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling</title>
</head>
<body>
<div id="parent">
<button id="child">Click Me</button>
</div>
<script>
document.getElementById("parent").addEventListener("click", function() {
console.log("Parent clicked");
});
document.getElementById("child").addEventListener("click", function() {
console.log("Child clicked");
});
</script>
</body>
</html>Output (when button is clicked):
Child clicked
Parent clicked
Notice how the child event handler executes first, then the parent’s. That’s bubbling in action.
At first, this might feel like just a technical detail, but it actually has big implications in real-world projects.
Imagine you have a list of items that keeps growing dynamically (e.g., a to-do list app). Instead of attaching a click listener to every new item, you can attach one to the parent <ul> and let bubbling do the job.
Sometimes, you don’t want an event to bubble or capture further. In those cases, you can use:
event.stopPropagation();
This method stops the event from moving to other ancestors.
Example
Copy Code
<div id="parent">
<button id="child">Click Me</button>
</div>
<script>
document.getElementById("parent").addEventListener("click", function() {
console.log("Parent clicked");
});
document.getElementById("child").addEventListener("click", function(event) {
console.log("Child clicked");
event.stopPropagation();
});
</script>Output (when button is clicked):
Child clicked
The parent never gets triggered because we stopped propagation.
One of the coolest applications of bubbling is event delegation. Instead of attaching listeners to multiple child elements, you add just one to the parent.
Example
Copy Code
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
document.getElementById("list").addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
console.log("You clicked on " + event.target.textContent);
}
});
</script>Here, even if you add new <li> items dynamically, the parent <ul> will still handle their clicks. That’s the power of bubbling.
| Feature | Event Capturing | Event Bubbling |
| Direction | Top → Target | Target → Top |
| Default Behavior | Not by default (need true) | Default in JavaScript |
| When to Use | Parent should catch first | Child-first, good for delegation |
Q1. Which is default: event bubbling or capturing?
Bubbling is the default behavior in JavaScript. Capturing only happens if you enable it manually.
Q2. When should I use capturing instead of bubbling?
Use capturing when you want higher-level elements (like a container or document) to handle events before the target element.
Q3. Can I disable bubbling?
Yes, you can stop bubbling using event.stopPropagation().
Q4. Is event delegation always better?
Not always. It’s great for dynamic elements, but for single static elements, direct listeners are fine.
Q5. Do all browsers support bubbling and capturing?
Yes, all modern browsers support both phases.
Event bubbling and capturing might sound like abstract concepts, but they’re simply about the path an event takes in the DOM. Bubbling (child to parent) is the default and most commonly used. Capturing (parent to child) can be enabled when needed.
If you learn to control propagation and apply event delegation smartly, you’ll not only write cleaner code but also build more efficient, scalable applications.
Want to dive deeper into such JavaScript fundamentals and advanced concepts? Check out Uncodemy’s JavaScript Course to strengthen your foundation and grow your skills as a developer.
Personalized learning paths with interactive materials and progress tracking for optimal learning experience.
Explore LMSCreate professional, ATS-optimized resumes tailored for tech roles with intelligent suggestions.
Build ResumeDetailed analysis of how your resume performs in Applicant Tracking Systems with actionable insights.
Check ResumeAI analyzes your code for efficiency, best practices, and bugs with instant feedback.
Try Code ReviewPractice coding in 20+ languages with our cloud-based compiler that works on any device.
Start Coding
TRENDING
BESTSELLER
BESTSELLER
TRENDING
HOT
BESTSELLER
HOT
BESTSELLER
BESTSELLER
HOT
POPULAR