JavaScript: Event Capturing and Bubbling [event propagation in detail]

If you are designing some event-heavy component using JavaScript, then the propagation of the event becomes very critical. Any event like “click”, “hover” etc. has 2 ways of traveling through the components.

Check this simple example-

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>BigBoxCode Simple Event Propagation</title>
  </head>
  <body>
    <div id="parent">
      <button id="child">Big Box Button</button>
    </div>
  </body>
  <script>
    const parentElement = document.getElementById("parent");
    const childElement = document.getElementById("child");

    // Add a click event listener to the child element
    childElement.addEventListener("click", (e) => {
      console.log("Click event triggered for - child (button)");
    });

    // Add a click evnet listener to the parent element
    parentElement.addEventListener("click", (e) => {
      console.log("Click event triggered for - parent (div)");
    });

    // Add a click event listener to the body
    document.body.addEventListener("click", (e) => {
      console.log("Click event triggered for - body");
    });

    // Add a click evnet listener to the document
    document.addEventListener("click", (e) => {
      console.log("Click event triggered for - document");
    });
  </script>
</html>

Save this HTML in a file and open it in a browser. Here we have one “div” element inside the body, and then a “button” inside the div.

In the JS code, we have added “click” event listeners for the – button, div, document body, and the document.

Click on the button and check the browser console. You will see the following logs.

Click event triggered for - child (button)

Click event triggered for - parent (div)

Click event triggered for - body

Click event triggered for - document

Though we have clicked only on the “button” element, but the “click” event is triggered for 4 elements, for the -“child”(button), “parent”(div), HTML document body, and the HTML document.

The same process of the event triggering is true for all events – “click”, “mouseover”, “mouseout”, etc.

There is a specific sequence these events are triggered. As a rule of thumb, we can think of these propagations as –

  • Capturing = event propagates down (from parent to child).
  • Bubbling = event propagates up (from child to parent).
JS event capturing vs bubbling simple view
JS event capturing vs bubbling simple view

To understand the capturing and bubbling, we need to understand the params of “addEventListener” method of EventTarget. Here is the signature of “addEventListener“-

HTMLElement.addEventListener<"click">(
    type: "click", 
    listener: (this: HTMLElement, ev: MouseEvent) => any, 
    options?: boolean | AddEventListenerOptions | undefined): void
)

For the capturing and bubbling, we will concentrate on the 3rd parameter, “options“.

We can pass a boolean value as a third parameter. In that case, the param is named “useCapture“. If we pass “true” as “useCapture” then it will do capturing, and will bubble otherwise-

  • options = true : event will capture in this case
  • options = false : event will bubble. as false is the default value of “useCapture”, so we can leave it in case of bubbling.

We can pass it as an object to represent “AddEventListenerOptions”, as the object property named “capture”-

  • options = { capture: true } : event will capture in this case
  • options = { capture: false } : event will bubble. as “capture” has a default value of “false” so we can ignore it if we want to.

RULE OF THUMB

Events will bubble by default.

We have to pass the capture param as true to enable event capturing.

Check the details of the “addEventListener” using the following link-

Event Bubbling

In event bubbling, the event is propagated from the clicked event to the parents. So the clicked element event is triggered first, then the event of the immediate parent is triggered, and then the event of its parent. It goes on and on until it reaches the final “document”.

We can define if the event will bubble while adding the event listener to the element.

someElement.addEventListener("click", (e) => {
    console.log("Event triggered for someElement");
}, false);
// This third param value "false" can be ignored, as "false" is the default vlaue for "useCaptuer"

Notice that we have passed a third parameter “false” for the “useCaptuer“.

As the third param “useCapture” has a default value is “false“, this can be ignored. The following code will work the same as the above.

someElement.addEventListener("click", (e) => {
    console.log("Event triggered for someElement");
});

We can also pass the capture param as a property of options. The following code will also have the same result-

someElement.addEventListener("click", (e) => {
    console.log("Event triggered for someElement");
}, { capture: false });
// captuer has default value of "false", so the third param can be ignored in this case
// But pass false, in case you have to pass the capture

Event Capturing

In event capturing the event starts to trigger for the parent, then propagates to the child, and then to the child of that.

The event of the main target element is triggered at last.

We can define if the event will capture by providing the last param of “addEventListener” as true-

someElement.addEventListener("click", (e) => {
    console.log("Event triggered for someElement");
}, true);
// This third param "useCaptuer" value is "true"

Notice that we have passed a third parameter “true” for the “useCaptuer“.

We can also pass the capture param as a property of options. The following code will also have the same result-

someElement.addEventListener("click", (e) => {
    console.log("Event triggered for someElement");
}, { capture: true});

Bubbling and Capturing Precedence

Let’s check what happens if we register 2 separate event listeners for the same element. One has event bubbling enabled, and the other has event capturing enabled. Check the following code-

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>BigBoxCode Event Bubble and Capture Precedence</title>
  </head>
  <body>
    <div id="parent">
      <button id="child">Big Box Button</button>
    </div>
  </body>
  <script>
    const parentElement = document.getElementById("parent");
    const childElement = document.getElementById("child");

    // Add a click event listener to the child element
    // This one has bubbling enabled
    childElement.addEventListener("click", (e) => {
      console.log("Click event triggered for - child (button) [ Event Bubbling ]");
    });

    // Add another click event listener to the child element
    // This one has capturing enabled
    childElement.addEventListener("click", (e) => {
      console.log("Click event triggered for - child (button) [ Event Capturing ]");
    }, true); // Capturing is enabled for this

    // Add a click evnet listener to the parent element
    parentElement.addEventListener("click", (e) => {
      console.log("Click event triggered for - parent (div)");
    });

    // Add a click event listener to the body
    document.body.addEventListener("click", (e) => {
      console.log("Click event triggered for - body");
    });

    // Add a click evnet listener to the document
    document.addEventListener("click", (e) => {      
      console.log("Click event triggered for - document");
    });
  </script>
</html>

If we click on the button and check the console, we get the following output-

Click event triggered for - child (button) [ Event Capturing ]
Click event triggered for - child (button) [ Event Bubbling ]

Click event triggered for - parent (div)
Click event triggered for - body
Click event triggered for - document

Event capturing has a higher precedence than bubbling.
If 2 separate event listener is defined for the same element, one has capturing, and the other one has bubbling, then the capturing event is triggered first, then the bubbling event.

Let’s register capturing and bubbling for all the click events for all the elements-

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>BigBoxCode Event Bubble and Capture Precedence</title>
  </head>
  <body>
    <div id="parent">
      <button id="child">Big Box Button</button>
    </div>
  </body>
  <script>
    const parentElement = document.getElementById("parent");
    const childElement = document.getElementById("child");

    // Add a click event listener to the child element
    // This one has bubbling enabled
    childElement.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - child (button) [ Event Bubbling ]"
      );
    });

    // Add another click event listener to the child element
    // This one has capturing enabled
    childElement.addEventListener(
      "click",
      (e) => {
        console.log(
          "Click event triggered for - child (button) [ Event Capturing ]"
        );
      },
      true // Capturing is enabled for this
    );

    // Add a click evnet listener to the parent element
    // This one has bubbling enabled
    parentElement.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - parent (div) [ Event Bubbling ]"
      );
    });

    // Add a click evnet listener to the parent element
    // This one has capturing enabled
    parentElement.addEventListener(
      "click",
      (e) => {
        console.log(
          "Click event triggered for - parent (div) [ Event Capturing ]"
        );
      },
      true // Capturing is enabled for this
    );

    // Add a click event listener to the body
    // This one has bubbling enabled
    document.body.addEventListener("click", (e) => {
      console.log("Click event triggered for - body [ Event Bubbling ]");
    });

    // Add a click event listener to the body
    // This one has capturing enabled
    document.body.addEventListener(
      "click",
      (e) => {
        console.log("Click event triggered for - body [ Event Capturing ]");
      },
      true // Capturing is enabled for this
    );

    // Add a click evnet listener to the document
    // This one has bubbling enabled
    document.addEventListener("click", (e) => {
      console.log("Click event triggered for - document [ Event Bubbling ]");
    });

    // Add a click evnet listener to the document
    // This one has capturing enabled
    document.addEventListener(
      "click",
      (e) => {
        console.log("Click event triggered for - document [ Event Capturing ]");
      },
      true // Capturing is enabled for this
    );
  </script>
</html>

We get logs like below-

Click event triggered for - document [ Event Capturing ]
Click event triggered for - body [ Event Capturing ]
Click event triggered for - parent (div) [ Event Capturing ]
Click event triggered for - child (button) [ Event Capturing ]
Click event triggered for - child (button) [ Event Bubbling ]
Click event triggered for - parent (div) [ Event Bubbling ]
Click event triggered for - body [ Event Bubbling ]
Click event triggered for - document [ Event Bubbling ]

So, all the capturing events are triggered first, and then all the bubbling events for the same elements are triggered.

Original Event Target

We have seen that the events will bubble or capture based on the provided configuration.

Now the question is, can we identify the original element from which this event was triggered?

The answer is yes. We can easily get the original event target by using event.target, in any event listener.

Check the example below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>BigBoxCode Event Target in Bubble and Capture</title>
  </head>
  <body>
    <div id="parent">
      <button id="child">Big Box Button</button>
    </div>
  </body>
  <script>
    const parentElement = document.getElementById("parent");
    const childElement = document.getElementById("child");

    // Add a click event listener to the child element
    childElement.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - child (button) || Event triggered from source: ",
        e.target
      );
    });

    // Add a click evnet listener to the parent element
    parentElement.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - parent (div) || Event triggered from source: ",
        e.target
      );
    });

    // Add a click event listener to the body
    document.body.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - body || Event triggered from source: ",
        e.target
      );
    });

    // Add a click evnet listener to the document
    document.addEventListener("click", (e) => {
      console.log(
        "Click event triggered for - document || Event triggered from source: ",
        e.target
      );
    });
  </script>
</html>

We will get the following output if we click on the button-

Click event triggered for - child (button) || Event triggered from source:  <button id=​"child">​Big Box Button​</button>​
Click event triggered for - parent (div) || Event triggered from source:  <button id=​"child">​Big Box Button​</button>​
Click event triggered for - body || Event triggered from source:  <button id=​"child">​Big Box Button​</button>​
Click event triggered for - document || Event triggered from source:  <button id=​"child">​Big Box Button​</button>​

We can see that, using the event.target, we get the original element from where the event was originally triggered.

Stop Event Propagation

To stop event propagation, we can call the “stopPropagation” inside the function (passed to the “addEventListener”), like in the code below-

someElement.addEventListener("click", (e) => {
    // following line will stop the propagation of the event
    e.stopPropagation();

    // your code here
    
});

We can also use the method “stopImmediatePropagation”. This method call will stop the propagation of the event, and additionally, it will stop all other listeners of the same element. Check the code below-

someElement.addEventListener("click", (e) => {
    // Following line will stop the propagation of the event
    // and will also prevent other event listener of the same element
    e.stopImmediatePropagation();

    // your code here
    
});

// Another click listener is written somewhere else
someElement.addEventListener("click", (e) => {
    // This listerner will not be reached
    // as we have used "stopImmediatePropagation"
    // in the other listener of the same element


    // your code here
    
});

Examples

Check the following examples of event capturing and bubbling. Here we have all the possible cases of event propagation-

For the following examples we have 4 elements-

  • Item 1: main parent div, holding all the elements.
  • Item 2: div inside “Item 1”.
  • Item 3: div inside “Item 2”.
  • Button: button inside “Item 3”

So the hierarchy looks like-

Item 1 => Item 2 => Item 3 => Button

Here is the representation of the items-

JS Event Bubbling and Capturing Example Elements
JS Event Bubbling and Capturing Example Elements

Example #1: Bubbling all Events

In this example we have bubbling enabled for all 4 elements-

ItemEvent Propagation type
Item 1bubbling
Item 2bubbling
Item 3bubbling
Buttonbubbling

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event Bubbling Example</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = false)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = false)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = false)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = false)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    });

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    });

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    });

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    });
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

bugboxbuttton clicked
item3 clicked
item2 clicked
item1 clicked
JS Event Bubbling Example
JS Event Bubbling Example

Example #2: Capturing all Events

In this example we have capturing enabled for all 4 elements-

ItemEvent Propagation type
Item 1capturing
Item 2capturing
Item 3capturing
Buttoncapturing

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event Capturing Example</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = true)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = true)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = true)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = true)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    }, true);

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    }, true);

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    }, true);

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    }, true);
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

item1 clicked
item2 clicked
item3 clicked
bigboxbutton clicked
JS Event Capturing Example
JS Event Capturing Example

Example #3: Capturing Parent and Bubbling Others

In this example, we have capturing for the main parent element, and bubbling enabled for other 3 elements-

ItemEvent Propagation type
Item 1capturing
Item 2bubbling
Item 3bubbling
Buttonbubbling

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example 3 - Event Capturing & Bubbling</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing & Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = true)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = false)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = false)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = false)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    }, true);

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    });

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    });

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    });
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

item1 clicked
bigboxbutton clicked
item3 clicked
item2 clicked
JS Event Capturing and Bubbling Example
JS Event Capturing and Bubbling Example

Example #4: Capturing 2 Parents and Bubbling Children

In this example we have capturing enabled for 2 top parents, and bubbling enabled children-

ItemEvent Propagation type
Item 1capturing
Item 2capturing
Item 3bubbling
Buttonbubbling

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example 4 - Event Capturing & Bubbling</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing & Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = true)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = true)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = false)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = false)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    }, true);

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    }, true);

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    });

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    });
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

item1 clicked
item2 clicked
bigboxbutton clicked
item3 clicked
JS Event Capturing and Bubbling Example
JS Event Capturing and Bubbling Example

Example #5: Capturing the Child and Bubbling all Parents

In this example, we have capturing enabled for 3 top parents, and bubbling for the button-

ItemEvent Propagation type
Item 1bubbling
Item 2bubbling
Item 3bubbling
Buttoncapturing

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example 5 - Event Capturing & Bubbling</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing & Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = false)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = false)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = false)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = true)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    });

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    });

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    });

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    }, true);
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

bigboxbutton clicked
item3 clicked
item2 clicked
item1 clicked
JS Event Capturing and Bubbling Example
JS Event Capturing and Bubbling Example

Example #6: Bubbling 2 Parents and Capturing 2 Children

In this example, we have capturing enabled for 3 top parents, and bubbling for the button-

ItemEvent Propagation type
Item 1bubbling
Item 2bubbling
Item 3capturing
Buttoncapturing

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example 6 - Event Capturing & Bubbling</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing & Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = false)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = false)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = true)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = true)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    });

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    });

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    }, true);

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    }, true);
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

item3 clicked
bigboxbutton clicked
item2 clicked
item1 clicked
JS Event Capturing and Bubbling Example
JS Event Capturing and Bubbling Example

Example #7: Capturing and Bubbling One-by-One

In this example, we have capturing enabled for 3 top parents, and bubbling for the button-

ItemEvent Propagation type
Item 1bubbling
Item 2capturing
Item 3bubbling
Buttoncapturing

Check the code below-

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example 7 - Event Capturing & Bubbling</title>

    <style>
      .sample-box {margin: 60px;padding: 20px 40px;color: white;font-size: 22px;}#item1 {background-color: red;}#item2 {background-color: green;}#item3 {background-color: blue;}#bigboxbutton {margin: 40px;padding: 20px;font-size: 20px;}
    </style>
  </head>
  <body>
    <header>
      <h1>Event Capturing & Bubbling Example</h1>
      <p>Check browser console for logs</p>
    </header>

    <section class="sample-box">
      <div id="item1" class="sample-box">
        <p><strong>Item 1</strong> (useCapture = false)</p>

        <div id="item2" class="sample-box">
          <p><strong>Item 2</strong> (useCapture = true)</p>

          <div id="item3" class="sample-box">
            <p><strong>Item 3</strong> (useCapture = false)</p>

            <button id="bigboxbutton"><strong>Click this button</strong> (useCapture = true)</button>
          </div>
        </div>
      </div>
    </section>
  </body>

  <script>
    const item1 = document.getElementById("item1");
    const item2 = document.getElementById("item2");
    const item3 = document.getElementById("item3");
    const bigBoxButton = document.getElementById("bigboxbutton");

    item1.addEventListener("click", function (e) {
      console.log("item1 clicked");
    });

    item2.addEventListener("click", function (e) {
      console.log("item2 clicked");
    }, true);

    item3.addEventListener("click", function (e) {
      console.log("item3 clicked");
    });

    bigBoxButton.addEventListener("click", function (e) {
      console.log("bigboxbutton clicked");
    }, true);
  </script>
</html>

Result:

If we click on the button and check the console, we will see the following log-

item2 clicked
bigboxbutton clicked
item3 clicked
item1 clicked
JS Event Capturing and Bubbling Example
JS Event Capturing and Bubbling Example

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.