Javascript Essentials — Event Bubbling and Event Capturing

Javascript Essentials — Event Bubbling and Event Capturing

Javascript is a great language. It has a simple syntax and a great community. If you’ve previously worked with Javascript you may know its nature, it can make you laugh some day or other. Working with JS can really be frustrating sometimes. I’m here to make you frustrate again with the topic of this post Event Bubbling and Event Capturing.

Event flow from HTML to JSEvent flow from HTML to JS

An event in JS is self-explanatory. An event may be ‘click’, ‘load’, ‘keyup’ etc. Code associated with the event executes when the event is triggered. There may be some other event-triggered too if an event on a particular element is triggered by the user. This happens if an event is associated with the element, another event with its parent and so on. So, it may seem confusing that which event may trigger first parent’s or children’s. Event flow consists of three phases:-

  1. Capturing phase.

  2. Target phase.

  3. Bubbling phase.

Well, it can be thought of something like this —

<div id="grandparent">
 <div id="parent">
   <button id="child">Click Me</button>
  </div>
</div>

And now adding the script —

document.getElementById('grandparent').addEventListener('click', function(){
console.log("Grand Parent is clicked");
});
document.getElementById('parent').addEventListener('click', function(){
console.log("Parent is clicked");
});
document.getElementById('child').addEventListener('click', function(){
console.log("Child is clicked");
});

Now, I’ll give you time to predict the output in the console.

.

.

.

The output will be in the following order —

Child is clicked
Parent is clicked
Grand Parent is clicked

Discovered something, yes if parent, grandparent and children all have an event associated with them, the event associated with the child or target gets fired first, and then parent, grandparent so on. The event gets fired in the order of the deepest element(child/target) in the DOM to outermost(grandparent) element, just like bubbles coming up from bottom to surface when you open a soda bottle. This is basically an event bubbling.

Sometimes, you don’t want your script to follow the bubbling principle, so you might need to stop event bubbling. You can do it by adding an onclick event with value “event.stopPropagation()” to the element till where you want bubbling principle to be followed. Considering an example for the same

<button id="child" onclick="event.stopPropagation()">Click Me</button>

Adding the above onclick event to the button with an id of ‘child’ will change the output in the console too —

Child is clicked

Calling ‘event.stopPropagation()’ function on ‘onclick’ event will stop bubbling up the event and will restrict the bubbling principle to be followed up to the element where it is added.

Coming to event capturing, this can be considered as the bubbles going down from the surface to bottom when you open a soda bottle, just the opposite of what event bubbling is. The event gets fired in the order of the outermost (parent/grandparent) in the DOM to deepes(child/target) element.

How can you make capturing of events possible in your script?

Well, ‘addEventListener()’ function in the DOM also takes a third argument called ‘useCapture’ which must have a value of true or false. By default, false is passed as an argument which will use bubbling propagation. A true value of ‘useCapture’ will use capturing propagation.

Now, considering the same template.html file and script2.js as follows —

document.getElementById('grandparent').addEventListener('click', function(){
console.log("Grand Parent is clicked");
}, true);
document.getElementById('parent').addEventListener('click', function(){
console.log("Parent is clicked");
}, true);
document.getElementById('child').addEventListener('click', function(){
console.log("Child is clicked");
}, true);

It is pretty clear what will be output now —

Grand Parent is clicked
Parent is clicked
Child is clicked

This is what you call event capturing.

These concepts can be frustrating sometimes but you will ultimately become acquainted when you mess your head around them.

Thank you for reading the blog. Do drop your feedback in the comments below and if you liked it, share it with your developer friends who might find it useful too. If you want to have any discussion around this topic, feel free to reach out to me on Twitter