Last Updated : 31 Jul, 2025
Event bubbling in JavaScript is a mechanism where an event triggered on a child element propagates upward through its ancestors in the DOM. It allows parent elements to respond to events triggered by their child elements.
Let's see this with an exmple
HTML
<!--Driver Code Starts-->
<html>
<head>
<style>
*{
margin: 25px;
box-sizing: border-box;
}
.grandparent{
height: 350px;
width: 350px;
border: 2px solid red;
}
.parent{
height: 250px;
width: 250px;
border: 2px solid blue;
}
.child{
height: 150px;
width: 150px;
border: 2px solid green;
}
</style>
</head>
<body>
<div class="grandparent" id="one">
Grandparent
<div class="parent" id="two">
Parent
<div class="child" id="three">
Child
</div>
</div>
</div>
<!--Driver Code Ends-->
<script>
let grandparent=document.getElementById('one')
let parent=document.getElementById('two')
let child=document.getElementById('three')
grandparent.addEventListener('click',function(e){
console.log("Grandparent Clicked")
})
parent.addEventListener('click',function(e){
console.log("Parent Clicked")
})
child.addEventListener('click',function(e){
console.log("Child Clicked")
})
</script>
<!--Driver Code Starts-->
</body>
</html>
<!--Driver Code Ends-->
To stop event bubbling, you can use the event e.stopPropagation() method in the event handler. This prevents the event from propagating to parent elements, so only the target element's event listener is triggered.
HTML
<!--Driver Code Starts-->
<html>
<head>
<style>
*{
margin: 25px;
box-sizing: border-box;
}
.grandparent{
height: 350px;
width: 350px;
border: 2px solid red;
}
.parent{
height: 250px;
width: 250px;
border: 2px solid blue;
}
.child{
height: 150px;
width: 150px;
border: 2px solid green;
}
</style>
</head>
<body>
<div class="grandparent" id="one">
Grandparent
<div class="parent" id="two">
Parent
<div class="child" id="three">
Child
</div>
</div>
</div>
<!--Driver Code Ends-->
<script>
let grandparent=document.getElementById('one')
let parent=document.getElementById('two')
let child=document.getElementById('three')
grandparent.addEventListener('click',function(e){
e.stopPropagation()
console.log("Grandparent Clicked")
})
parent.addEventListener('click',function(e){
e.stopPropagation()
console.log("Parent Clicked")
})
child.addEventListener('click',function(e){
e.stopPropagation()
console.log("Child Clicked")
})
</script>
<!--Driver Code Starts-->
</body>
</html>
<!--Driver Code Ends-->
document.getElementById('parent').addEventListener('click', (event) => {
console.log('Clicked:', event.target.id);
});
The event starts at the target element and propagates upward to the root of the DOM.
The event starts at the root of the DOM and propagates downward to the target element.
Event listeners are attached to handle events during the bubbling phase by default.
To handle events in the capturing phase, you must explicitly set the capture option to true in addEventListener.
Often used when you want parent elements to respond to events triggered on child elements (e.g., event delegation).
Useful when you want parent elements to handle the event before it reaches the target element.
Inner (child) elements execute their event listeners first, followed by outer (parent) elements as the event propagates upward.
Outer (parent) elements execute their event listeners first, followed by inner (child) elements as the event propagates downward.
Supported by all modern browsers and has been the default behavior for a long time.
Supported, but less commonly used as it requires the explicit capture option to be enabled.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4