Events in javascript have been consistently used in the case of manipulation of the page either by browser or user. In this blog, let's understand two important events in Javascript, i.e. Event bubbling and Event capturing. There are basically two ways of event propagation in the DOM tree.
Now, let's try to understand the event bubbling with the help of an example.
Here we have a div named outer
which has a nested div middle
which has another nested div inner
. Now we are attaching a click event handler on all the divs which displays its respective color and position
Now let's test this code
<body>
<div class="outer">
<div class="middle">
<div class="inner"></div>
</div>
</div>
<script>
const outer = document.querySelector(".outer");
const middle = document.querySelector(".middle");
const inner = document.querySelector(".inner");
outer.addEventListener("click", () => {
console.log("I am outer div pink",);
});
middle.addEventListener("click", () => {
console.log("I am middle div yellow");
});
inner.addEventListener("click", () => {
console.log("I am inner div green");
});
</script>
</body>
Output:
Now when we click on the inner div, we observe that it initially displays inner, then middle, and finally the outer div. But we just clicked on the inner div, so how did all the parent elements got triggered??๐ The reason is the event bubbling.
Event Bubbling
The bubbling principle is simple.
When an event is triggered on an element, it initially runs the handlers on it, then on its parent, then all the way above to its ancestors. Basically here events are propagated up in the hierarchy, i.e. the inner, middle, and lastly the outer.
Note: addEventListener accepts 3 parameters- the type of event which is needed to be executed, the callback function and the useCapture.useCapture is generally ignored in most cases, but we will need this here in order to understand event capturing in detail.
Now in order to understand event capturing, we will need to understand the useCapture flag. UseCapture denotes a boolean value which is needed to be passed in order to activate the flags. UseCapture flag in default in false
Capturing almost resembles the bubbling event, with just the difference that in capturing, events are propagated down the hierarchy. In order to activate capturing, we need to enable the useCapture to true.
Let's go again and see this in action with the help of our initial code.
outer.addEventListener("click", () => {
console.log("I am outer div pink",);
},true);
middle.addEventListener("click", () => {
console.log("I am middle div yellow");
},true);
inner.addEventListener("click", () => {
console.log("I am inner div green");
},true);
There's also a special method i.e. e.stopPropogation(), so if we want the click to be only associated with this child, and doesn't trigger the whole propagation cycle then we could use this method.
Why is this used anyway and which is the better option?
Their usecase pertains when we have event listeners on both parent and the child, and we have to prioritize the events based on our program. At such times, we can use bubbling or capturing according to our program. And which is better that basically depends upon your program. There are times when you would use even a combination on both events!
So, to summarize, Event bubbling fires events up the hierarchy and event capturing fires events down the hierarchy.