JavaScript Event Bubbling and Capturing

Introduction:

One of the key features of JavaScript is its event handling capability. Events are actions or occurrences that happen in the browser, such as a user clicking on a button or typing in a form field. Event handling involves writing code that responds to these events.

JavaScript Event Bubbling and Capturing:

Event bubbling and capturing are two different ways in which events can propagate through the DOM (Document Object Model) tree. In other words, they describe how the event travels from the target element to its parent and ancestor elements.

  1. Event Bubbling:

    Event bubbling is the most common way events propagate through the DOM. When an event occurs on an element, it first triggers the event on the target element and then bubbles up to its parent and ancestor elements. This means that the event handlers on the parent and ancestor elements will also be triggered.

For example, consider the following HTML code:

<div class="parent">
  <div class="child">
    <button>Click me!</button>
  </div>
</div>

Suppose we have attached click event listeners to both the parent and child elements:

const parent = document.querySelector('.parent');
const child = document.querySelector('.child');

parent.addEventListener('click', function() {
  alert('Clicked on parent!');
});

child.addEventListener('click', function() {
  alert('Clicked on child!');
});

Here's the complete code that you can try and see the result:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      .parent {
        background-color: #f2f2f2;
        padding: 20px;
        text-align: center;
      }
      .child {
        background-color: #d9d9d9;
        padding: 20px;
        text-align: center;
      }
      button {
        background-color: #4caf50;
        border: none;
        color: white;
        padding: 10px;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 16px;
        margin: 4px 2px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child">
        <button>Click me!</button>
      </div>
    </div>

    <script>
      const parent = document.querySelector(".parent");
      const child = document.querySelector(".child");

      parent.addEventListener("click", function () {
        alert("Clicked on parent!");
      });

      child.addEventListener("click", function () {
        alert("Clicked on child!");
      });
    </script>
  </body>
</html>

If we click on the button element, the events will bubble up in the following order:

child -> parent

This means that both event handlers will be triggered, and we will see two alert messages, one for each element.

  1. Event Capturing:

    Event capturing is the opposite of event bubbling. When an event occurs on an element, it triggers the event on the target element's ancestors first before reaching the target element. This means that the event handlers on the ancestor elements will be triggered first, followed by the target element's event handler.

To use event capturing, we need to set the capture option to true when adding the event listener:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      .parent {
        background-color: #f2f2f2;
        padding: 20px;
        text-align: center;
      }
      .child {
        background-color: #d9d9d9;
        padding: 20px;
        text-align: center;
      }
      button {
        background-color: #4caf50;
        border: none;
        color: white;
        padding: 10px;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 16px;
        margin: 4px 2px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child">
        <button>Click me!</button>
      </div>
    </div>

    <script>
      const parent = document.querySelector(".parent");
      const child = document.querySelector(".child");

      /** add true here **/
      parent.addEventListener(
        "click",
        function () {
          alert("Clicked on parent!");
        },
        true
      );

      child.addEventListener("click", function () {
        alert("Clicked on child!");
      });
    </script>
  </body>
</html>

If we click on the button element, the events will capture down in the following order:

parent -> child

This means that the capturing event handler will be triggered first, followed by the target element's event handler.

Summary:

In summary, event bubbling and capturing are two different ways in which events can propagate through the DOM. Bubbling is the default behavior, where events first trigger on the target element and then bubble up to its parent and ancestor elements. Capturing, on the other hand, triggers events on the ancestor elements first before reaching the target element. By understanding the difference between event bubbling and capturing, we can write more effective event handling code that responds to user interactions in a more precise and efficient way.

Practice Your Knowledge

What are the two phases of event propagation mentioned in the provided URL?

Quiz Time: Test Your Skills!

Ready to challenge what you've learned? Dive into our interactive quizzes for a deeper understanding and a fun way to reinforce your knowledge.

Do you find this helpful?