JS: Event Bubble
Tags: javascript, webdev
Published: 2023-09-28 03:44:53

Before understanding what event bubble means, lets look at the following scenario. 

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event Bubble</title>
  </head>
  <body>
    <section id="main-container">
      <h1>My Shopping List</h1>
      <ul id="list-container">
        <li id="item-1">Fruits</li>
        <li>Vegetables</li>
        <li>Milk</li>
        <li>Rice</li>
      </ul>
    </section>
  </body>
</html>
```
Here, we have simple html file where we have listed down our shopping items. Now lets add some click event listeners. 

```

document.getElementById("item-1").addEventListener("click", function () {
        console.log("item-1: Fruits is clicked");
      });
    
```
What will happen if we click on the first item of our list, Fruits? We should get "item-1: Fruits is clicked" in the console, right?

![Click event at item-1: Fruits](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4vupgfnswwcr9rlbmiaq.png)

What will happen if we try to add a click event listener to `ul` with `id="list-container"` ? Let's find out.

```
 document
        .getElementById("list-container")
        .addEventListener("click", function () {
          console.log("list-container is clicked");
        });
```
Now if we click any items on the `ul`, except item-1: Fruits, we will get "list-container is clicked" as output.
Means, if you click Vegetables, Milk or Rice, you will get the following output.  

![Click event after clicking other items except Fruits](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gb0yxtaux1nvp179tgzn.png)

For item-1: Fruits, if we click it now then we will get two outputs.

1. item-1: Fruits is clicked
2. list-container is clicked

![Click event at item-1:Fruits](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9h2kuny5lwvb1w7nwz11.png)

Now, lets add another event listener to our main-container. 

```
document
          .getElementById("main-container")
          .addEventListener("click", function () {
            console.log("main-container is clicked");
          });
```
Now what will happen if we click inside our main-container? For example, if we click on the `h1` tag, we should get "main-container is clicked" as output, right? 
But if we click on item-1: Fruits, then we will have 3 outputs:

1. item-1: Fruits is clicked
2. list-container is clicked
3. main-container is clicked

![Click event at item-1: Fruits](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7zwbunrl33owv52qr77r.png)

On the other hand, if we click any other items on the list, we will have two outputs. 

1. list-container is clicked
2. main-container is clicked

![Click event inside the container except for item-1: Fruits](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/itgo2p2s8xic28g30fmv.png)

Here, we are observing that the events are triggered from bottom to top, just like bubbles in water or soda. This scenario is known as event bubble.

There is another simple way to understand this scenario. Suppose you live in Paris. It means that the statement "You live in France" is true. Also, "You live in Europe" is also true. Just like event bubbling. The event is first captured and handled by the lower most element and then it is  propagated upwards. Bottom --> Top.

Now is there any way to stop this? The answer is "Yes!". Here's how: 
Suppose we want to stop event propagation for our item-1: Fruits. We just need to call the `stopPropagation` method, simple....

```
document.getElementById("item-1").addEventListener("click", function (event) {
        console.log("item-1: Fruits is clicked");
        event.stopPropagation();
      });
```
Now we will only get "item-1: Fruits is clicked" as we have stopped the propagation for this click event. 

There is also a method called `stopImmediatePropagation()` which is used when you have multiple events attached with the same item, and you need to stop others when performing one event.