Day 4: What is Event Bubbling and Capturing?

๐Ÿ’ฌ Just thinking from where you are getting all these questions daily? ๐Ÿ˜…

๐Ÿ˜ It is many times asked interview question.

Okay.Let's start with Bubbling.The bubbling principle is really simple.When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.

๐Ÿ™„ English please..

๐Ÿ˜† I was teasing you!! heheheLet's take one small example.Letโ€™s say we have 3 nested elements FORM > DIV > P with a onclick handler on each of them.<form onclick="alert('form')">
FORM
<div onclick="alert('div')">
DIV
<p onclick="alert('p')">
P
</p>
</div>
</form>

In this example, If you click on `p` element, You'll see alert with message `p` but also you will get alert `div` and alert `form`.
This process of propagating event to its parent element is called Bubbling.You can imagine a bubble inside water popping out, It happens the same way.

๐Ÿ™ƒ hmmmmmmmmm.. How this happens?

Actually, You don't need to do anything.Almost all events bubble.I said almost okay, there are few events for example `focus` event doesn't bubble.

Okay but what if I donโ€™t want this bubbling thing?

You can stop that actually.Any handler may decide that the event has been fully processed and stop the bubbling.The method for it, is event.stopPropagation().It stops that single event from bubbling.For Example:<body onclick="alert(`the bubbling doesn't reach here`)">
<button onclick="event.stopPropagation()">Click me</button>
</body>

In this example, If you click on `button` element nothing will happen but if you click elsewhere you will see an alert.

๐Ÿค” Stops single event ? What if i have multiple events on a single element?

It is possible, You can use event.stopImmediatePropagation() for this.

Why we have such a strange behaviour of bubbling events?

It's not strange.
Bubbling is convenient.
Donโ€™t stop it without a real need obvious and architecturally well thought out. Sometimes `event.stopPropagation()` creates hidden pitfalls that later may become problems.

๐Ÿค” What kind of pitfalls?

For example:- We create a nested menu. - Each submenu handles clicks on its elements and calls stopPropagation so that the outer menu wonโ€™t trigger.- Later we decide to catch clicks on the whole window, to track usersโ€™ behaviour (where people click). Some analytic systems do that. - Usually the code uses document.addEventListener('click'โ€ฆ) to catch all clicks.- In this case our analytics wonโ€™t work over the area where clicks are stopped by stopPropagation. Sadly, weโ€™ve got a โ€œdead zoneโ€ there.Thereโ€™s usually no real need to prevent the bubbling. A task that seemingly requires that may be solved by other means. One of them is to use custom events, we might cover them later.

๐Ÿฅด This is strange to be honest.

Yeah, but this is what event bubbling is!!

Okay, What about Event Capturing?

In simple words, It is opposite of bubbling. Event Capturing is also known as Event Trickling as it goes down from parent element to child or target element.To be honest, It's rarely used in real life, It's kind of like invisible to us. 

๐Ÿค” What do you mean by invisible?

Invisible means by default it is set to false. And you will be in really really rare situation where you are going to set it true.

hmm.. okay but just out of curiosity, I want to know from where I can set it?

To catch an event on the capturing phase, we need to set the handler capture option true.For example:You can set 3rd parameter as below.elem.addEventListener(..., {capture: true})// or, just "true" is an alias to {capture: true} elem.addEventListener(..., true)
You can try below code too!!
<form>FORM
<div>DIV
<p>P</p>
</div>
</form>
<script> for(let elem of document.querySelectorAll('*')) { elem.addEventListener(
"click", e => alert(`Capturing: ${elem.tagName}`), true
);
elem.addEventListener(
"click", e => alert(`Bubbling: ${elem.tagName}`)
);
}
</script>

Okay, but when I add any Event Listener at some point I remove it as well to avoid memory leakages. Do I have to use same third argument there as well?

You are absolutely correct!!If we addEventListener(..., true), then we should mention the same phase in removeEventListener(..., true) to correctly remove the handler.

Today, I feel like lot of jargon thrown at me ๐Ÿฅด.

Just copy paste those examples and try it out in the browser.I intentionally made it like this so you can easily copy code and try it yourself.

Ahhaa !! You are awesome man ๐Ÿคฉ.

I am trying my best ๐Ÿ˜‡So this was in a nutshell Event Bubbling and Capturing.See you tomorrow with another question ๐Ÿ‘‹And a humble reminder join me on Twitter, LinkedIn and Github.I share lot of cool tips and tricks regarding PHP, Laravel, Javascript, Vuejs, Nuxtjs, Reactjs, databases, workflows, productivity etc etc.https://twitter.com/rckstrbhushanhttps://www.linkedin.com/in/rckstrbhushanhttps://github.com/bhushan๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿป๐Ÿ‘†๐ŸปTake care and stay safe. Cheers ๐Ÿฅ‚

Cheers ๐Ÿฅ‚