1, the preface

All code demos in this article run in the Chrome browser.

Reading this article, you will learn:

1.Browser silent event propagation mechanism2.Capture, bubbling mechanism3.Prevents capture and bubbling4. `stopImmediatePropagation`and`stopPropagation`The difference betweenCopy the code

2. Event transmission mechanism

2.1 Default browser event propagation mechanism

(by default, the third argument to addEventListener is false); div1, div2;

<style>
  #div1 {
    width: 300px;
    padding: 15px;
    border: 2px solid black;
  }
  #div2 {
    width: 100px;
    padding: 5px;
    border: 2px solid darkorange;
  }
</style>

<body>
    <div id="div1">
      div1
      <div id="div2">
          div2
      </div>
    </div>
</body>
Copy the code

Js:

const div1 = document.querySelector("#div1");
const div2 = document.querySelector("#div2");

div1.addEventListener("click".function () {
    console.log("Div1 is clicked");
  });

div2.addEventListener("click".function () {
    console.log("Div2 is clicked");
});
Copy the code

Click div2 and print :div2 clicked, div1 clicked,

Conclusion: The default is to start with the target element and bubble execution (propagating from inside out).

2.2 Manual Settings to perform in capture or bubbling phases

Set (addEventListener with the third parameter set to true)div1 takes place during capture, div2 does not set the third parameter.

div1.addEventListener(
    "click".function () {
      console.log("Div1 is clicked");
    },
    true / / add + +
  );

div2.addEventListener("click".function () {
    console.log("Div2 is clicked");
});
Copy the code

Click div2 and print :div1 clicked, div2 clicked,

Conclusion: If the outer element is set to execute during the capture phase, the binding event for the outer element is triggered first

3, prevent bubbling, capture

3.1 How do I prevent events from being passed to the outer layer (prevent bubbling) when I click div2?

div1.addEventListener("click".function () {
    console.log("Div1 is clicked");
  });

  div2.addEventListener("click".function (e) {
    console.log("Div2 is clicked");
    e.stopPropagation();
    // e.stopImmediatePropagation(); // This can also be used to block
  });
Copy the code

Print only :div2 is clicked,

Conclusion: Use the stopPropagation or StopDynamic Propagation method to block in DIV2 (the difference between the two apis will be explained below).

3.2 Click div2, if div1 and div2 are executed in capture phase, how to prevent capture?

div1.addEventListener(
    "click".function (e) {
      console.log("Div1 is clicked");
      e.stopPropagation();
      // e.stopImmediatePropagation(); // Also prevents capture
    },
    true
  );

  div2.addEventListener(
    "click".function (e) {
      console.log("Div2 is clicked");
    },
    true
  );
Copy the code

Print only :div1 is clicked,

Conclusion: The stopPropagation or stopImmediatePropagation method can be used to prevent events from propagating during the capture phase.

4, stopImmediatePropagation

Since either stopPropagation or Stopdynamic Propagation can prevent bubbling or capture, what difference does it make?

What happens if we add a click event to div2 and then add the stopPropagation method to the first click event handler in div2?

Let’s start with stopPropagation:

div1.addEventListener("click".function (e) {
    console.log("Div1 is clicked");
  });

  div2.addEventListener("click".function (e) {
    e.stopPropagation();
    console.log("Event 1 div2 clicked");
  });

  div2.addEventListener("click".function (e) {
    console.log("Event 2 div2 was clicked");
  });
Copy the code

Not surprisingly, it prints in sequence: event 1 div2 is clicked, event 2 div2 is clicked (no printing div1 was clicked because it stopped bubbling in div2);

Placing the second click event code of div2 before the first click event code of div2 will print that event 2 div2 was clicked and event 1 div2 was clicked.

Conclusion: When multiple events are bound to the same element, the order in which they are executed depends on the order in which the code is bound

Then look at stopImmediatePropagation:

div1.addEventListener("click".function (e) {
    console.log("Div1 is clicked");
  });

  div2.addEventListener("click".function (e) {
    e.stopImmediatePropagation();
    console.log("Event 1 div2 clicked");
  });

  div2.addEventListener("click".function (e) {
    console.log("Event 2 div2 was clicked");
  });
Copy the code

Print only: event 1 div2 is clicked;

Conclusion: stopImmediatePropagation will interrupt the execution of subsequent events of the same element.

5, summary

  • Chrome’s default event propagation order is: Target element –> Bubble up;

  • The stopImmediatePropagation and stopPropagation:

    A. topPropagation: Prevents events from being transmitted in the bubble or capture phase, but does not prevent other event listeners listening to the same event from being called;

    B.s topImmediatePropagation: if more than one event listener is attached to the same element on the same event type of when this event is triggered, they can be added according to the order is invoked. If you execute stopImmediatePropagation() in one of the event listeners, none of the remaining event listeners will be called.