Event bubbling, capturing and how to prevent them

Shuvo - Oct 25 '21 - - Dev Community

Lets say you have a parent container that also has a child element inside it.



<div class="parent">
  <h1 class="child">hello</h1>
</div>


Enter fullscreen mode Exit fullscreen mode

And you have added a event listener to them.



const parent = document.querySelector(".parent")
const child = document.querySelector(".child")

parent.addEventListener("click", () => {
  console.log("Parent clicked!")
})

child.addEventListener("click", () => {
  console.log("child clicked!")
})


Enter fullscreen mode Exit fullscreen mode

Now try to click on just the parent. You should see Parent clicked!
But now if you try to click on the child element in the console you will see not only child clicked! was printed but Parent clicked! was also printed.
js event bubbling demo

Why is that? That is due do something called event bubbling. So when a event is emitted on the child it will bubble up to its parent.
And it makes sense if you think about it, the child element was sitting inside its parent. So we wanted to click on just the child but in reality we clicked on both the parent and the child. So both events were fired. Now notice that first child clicked! was printed and then Parent clicked! was printed. That means the even is first fired on the child then its bubbling up to its parent. But if we want we can make it do the opposite as well.
So to do that as the third argument of our addEventListener we can pass true. So if we do that you will see first Parent clicked! will be printed then child clicked!.



parent.addEventListener("click", () => {
  console.log("Parent clicked!")
}, true)

child.addEventListener("click", () => {
  console.log("child clicked!")
}, true)


Enter fullscreen mode Exit fullscreen mode

JavaScript event capturing demo

So basically passing true as the third argument of addEventListener tells JavaScript to use capturing mode instead of bubbling mode. And in capturing mode event is fired to the parent then goes down to its child which is the opposite of event bubbling.

Also if we want we can prevent event bubbling and event capturing by calling stopPropagation on the event. So if we click on child only the event listener set on child will be fired and if we click on parent only the event listener set on parent will be fired.



parent.addEventListener("click", (e) => {
  e.stopPropagation()
  console.log("Parent clicked!")
})

child.addEventListener("click", (e) => {
  e.stopPropagation()
  console.log("child clicked!")
})


Enter fullscreen mode Exit fullscreen mode

preventing event bubbling

Alight that's all for now. Make sure you check out my other articles and YouTube Channel

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .