Event Bubbling and Capturing in Javascript

Event Bubbling and Capturing in Javascript

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

  1. Capture phase
  2. Target phase
  3. 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.

  1. There are 3 phase in event propagation capture, target and bubble phase
  2. What is capturing?
  3. What is bubbling?
  4. isCapture parameter in event listener.
  5. How we can control the propagation flow using stopPropagation() method.

Thank you for reading...

References

  1. https://javascript.info/bubbling-and-capturing
  2. https://www.youtube.com/watch?v=aVSf0b1jVKk