Introduction.
We are working on lot of web applications using different kind of technologies, in those applications we use numerous types of nested elements also. So when we are using these nested elements it is necessary to know how the operation happens In these nested elements i.e is the data coming from inner element to outer element or from outer element to inner element. Let's understand this process by discussing about event bubbling and capturing process in javascript.
Event bubbling and capturing are the two ways of event propagation happens in the HTML DOM API. When Event occurs in nested structure event propagation mode determines the order in which the event should occur.
Event Propagation.
Propagation of the event mainly happens in 3 phases
- Capture phase
- Target phase
- Bubble phase
Let us consider piece of html code
<div id="grand-parent">
Grand Parent
<div id="parent">
Parent
<div id="child">Child</div>
</div>
</div>
and to assign events let's see the javascript code,
document.getElementById("grand-parent").addEventListener("click", () => {
console.log("Grand Parent Clicked");
});
document.getElementById("parent").addEventListener("click", () => {
console.log("Parent Clicked");
});
document.getElementById("child").addEventListener("click", () => {
console.log("Child Clicked");
});
Can you guess the order of events? Let's discuss about this, Since this is generic code the order of execution will be child > parent > grand-parent . What's the reason for this order? Now Bubbling and Capturing concepts comes into picture.
Syntax for bubbling and capturing is,
document.getElementById("element-selector").addEventListener("action", callback, isCapture);
here isCapture
determines the order of event execution. If isCapture
value is false
then bubbling else capturing is selected.
1.Capture Phase
What is Capturing?
Capturing means the execution starts from outermost and moves inward. This happens when isCapture
value is true
.
Let's see capturing in code.
document.getElementById("grand-parent").addEventListener("click", () => {
console.log("Grand Parent Clicked");
}, true);
document.getElementById("parent").addEventListener("click", () => {
console.log("Parent Clicked");
}, true);
document.getElementById("child").addEventListener("click", () => {
console.log("Child Clicked");
}, true);
order of execution will be grand-parent > parent > child
2. Target phase
In this phase, When the event reaches the target element it performs all the operations in the callback and continues to next event in the flow.
3.Bubble Phase
What is Bubbling?
As the name indicating bubbling means execution starts from innermost and moves outward. This happens when isCapture
value is false
and also if isCapture
field is not mentioned bubbling is selected by default.
Let's see bubbling in code.
document.getElementById("grand-parent").addEventListener("click", () => {
console.log("Grand Parent Clicked");
}, false);
document.getElementById("parent").addEventListener("click", () => {
console.log("Parent Clicked");
}, false);
document.getElementById("child").addEventListener("click", () => {
console.log("Child Clicked");
}, false);
order of execution will be child > parent > grand-parent
Actually propagation of event continues as per W3C rule, rule says capturing should happen first and then bubbling should happen.
How can we control the propagation?
For controlling the propagation there is a event method called stopPropagation()
. Let's see how we can control the propagation using stopPropagation
.
document.getElementById("grand-parent").addEventListener("click", (event) => {
console.log("Grand Parent Clicked");
}, true);
document.getElementById("parent").addEventListener("click", (event) => {
console.log("Parent Clicked");
event.stopPropagation()
}, true);
document.getElementById("child").addEventListener("click", (event) => {
console.log("Child Clicked");
}, true);
Here in this example, stopPropagation attached to event in Parent block. At first capturing process starts means wherever isCapture
is true
considers those and stops wherever stopPropagation encountered, and it will not continue to check any bubbling events. so now only Grand Parent Clicked
and Parent Clicked
prints.
Let's see another example,
document.getElementById("grand-parent").addEventListener("click", (event) => {
console.log("Grand Parent Clicked");
}, true);
document.getElementById("parent").addEventListener("click", (event) => {
console.log("Parent Clicked");
}, false);
document.getElementById("child").addEventListener("click", (event) => {
console.log("Child Clicked");
event.stopPropagation()
}, false);
Here in this example, stopPropagation attached to event in Child block. At first capturing process starts means wherever isCapture
is true executes that, here only grand-parent is considered in capturing process so displays Grand Parent Clicked
, then bubbling process starts and prints Child Clicked
and stopPropagation encountered in child so propagation stops here.
Conclusion
In this small blog we saw how the event propagation process happens in javascript, let's summarize the learning.
- There are 3 phase in event propagation capture, target and bubble phase
- What is capturing?
- What is bubbling?
isCapture
parameter in event listener.- How we can control the propagation flow using
stopPropagation()
method.
Thank you for reading...