Introduction
In this article, we will see about Event Bubbling and Event Capturing in Javascript. Event propagation is how the events travel through the DOM tree to reach their target. Event Bubbling and Capturing are ways of event propagation in the HTML DOM tree.
Event Bubbling
Bubbling is the event that starts from the innermost or target element to its parents, then all its ancestors, which means events are propagated from bottom to top. Consider that element 'A' is present in the other element 'B', and both elements have a handler/listener for the same event (ex., click event). When an event happens on element 'A', then its event handler runs first, then on its parent's event handler will run. For all modern browser's default event flow is Event Bubbling.
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="grandparent">
<div id="parent">
<button id="child">Child</button>
</div>
</div>
<script>
<!-- Add click event on grandparent div -->
var grandParent = document.getElementById('grandparent');
grandParent.addEventListener('click', function(){
console.log("GrandParent Clicked");
});
<!-- Add click event on parent div -->
var parent = document.getElementById('parent');
parent.addEventListener('click', function(){
console.log("Parent Clicked");
});
<!-- Add click event on child button -->
var child = document.getElementById('child');
child.addEventListener('click', function(){
console.log("Child Clicked");
});
</script>
</body>
</html>
In the above code,
- I have two "div" elements. One "div" element with the id "grandparent" and another "div" element with the id "parent", which is a child of the "grandparent" div.
- I have one button with the id "child", a child of the "parent" div.
- I have attached the "click" event handler for all the above three elements (2 div and 1 button) using addEventListener(). Print the value using console.log () inside the "click" event handler, and print the value using console.log().
- When clicking on the "child" button, first runs the button's "click" event handler, then runs the "parent" div's "click" event handler, then the "grandparent" div's "click" event handler. The event has propagated from bottom to top.
Stop Event Bubbling
If you want to stop the event bubbling, use the event.stopPropagation() method in the event handler. Suppose you want to stop the event flow from the target to the top element in the DOM event.stopPropagation() method stops the event from traveling to the top.
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="grandparent">
<div id="parent">
<button id="child">Child</button>
</div>
</div>
<script>
<!-- Add click event on grandparent div -->
var grandParent = document.getElementById('grandparent');
grandParent.addEventListener('click', function(){
console.log("GrandParent Clicked");
});
<!-- Add click event on parent div -->
var parent = document.getElementById('parent');
parent.addEventListener('click', function(){
console.log("Parent Clicked");
});
<!-- Add click event on child button -->
var child = document.getElementById('child');
child.addEventListener('click', function(event){
event.stopPropagation();
console.log("Child Clicked");
});
</script>
</body>
</html>
Here I have added an event.stopPropagation() method in the child button's event handler prevents the event from propagating to its parent.
Event Capturing
Event Capturing is the event that starts from the topmost element to the target element, which means events are propagated from top to bottom. The modern browser doesn't support event capturing by default, but it can be done by code in JavaScript.
<!DOCTYPE html>
<html>
<head>
<title>Event Capturing Example</title>
</head>
<body>
<div id="grandparent">
<div id="parent">
<button id="child">Child</button>
</div>
</div>
<script>
<!-- Add click event on grandparent div -->
var grandParent = document.getElementById('grandparent');
grandParent.addEventListener('click', function(){
console.log("GrandParent Clicked");
}, true);
<!-- Add click event on parent div -->
var parent = document.getElementById('parent');
parent.addEventListener('click', function(){
console.log("Parent Clicked");
}, true);
<!-- Add click event on child button -->
var child = document.getElementById('child');
child.addEventListener('click', function(){
console.log("Child Clicked");
}, true);
</script>
</body>
</html>
The above example is the same as the Event bubbling example. By default, it is false. Still, the difference is enabling the event capturing flow by adding the third optional argument (boolean value) set to "true" for the "addEventListener()" function.
target.addEventListener(type, listener, useCapture);
The event has prophages from bottom to top. If you set it to "true", then the event flow will be top to bottom(target). When clicking on the "child" button, first runs the button's "click" event handler, then runs the "parent" div's "click" event handler, then the "grandparent" div's "click" event handler.
I hope you liked it and know about Event Bubbling and Event Capturing in JavaScript. Keep Learning !!!!