Let you learn DOM event flow

Posted by Swede78 on Wed, 15 Dec 2021 05:39:40 +0100

1. Common event binding methods

1.1 object attribute binding

<button id="btn">Point me</button>
<script>
  var btn = document.getElementById("btn");
  btn.onclick = function() {
    console.log("Event trigger")
  }
</script>

1.2 addEventListener() binding

<button id="btn">Point me</button>
<script>
  var btn = document.getElementById("btn");
  btn.addEventListener("click", function () { 
    console.log("Event trigger");
  });
</script>

The third parameter of addEventListener, Boolean type value, can specify whether the event bubble stage or capture stage is triggered. true - capture, false - bubble, default false, both bubble.

1.3 differences between the two methods

  • The object property binding method can only be bound once. If the same event type is bound repeatedly, the previous one will be overwritten by the later one

    In the following code, "event trigger - 1" will not be executed and is overwritten by onclick below
    In fact, this similar object attribute, the same key, will override the previous value if re assigned

    <button id="btn">Point me</button>
    <script>
    var btn = document.getElementById("btn");
    btn.onclick = function() {
      console.log("Event trigger-1")
    }
    btn.onclick = function() {
      console.log("Event trigger-2")
    }
    </script>

    *addEventListener does not have the problem of repeated binding coverage. The same element can bind the same event type multiple times

    In the following code, when the button is clicked, the event will__ Trigger in sequence__

    <button id="btn">Point me</button>
    <script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click", function () { 
      console.log("Event trigger-1");
    });
    btn.addEventListener("click", function () { 
      console.log("Event trigger-2");
    });
    btn.addEventListener("click", function () { 
      console.log("Event trigger-3");
    });
    </script>
  • addEventListener provides whether the event is triggered in the capture phase or in the bubble phase

    2. Event flow

    2.1 concept

    When an event occurs, it will propagate between the element node and the root node in a specific order. All nodes passing through the path will receive the event. This propagation process is the DOM event flow.

    2.2 sequence of events

    <div id="root">
    <button id="btn">Point me</button>
    </div>

    2.2. 1 capture phase

    Click button on the page. First, the document receives the click event, and then goes down the dom tree until the actual event triggers the element, that is, the button node. This process is called the event capture process, which is a propagation process from outside to inside.

    2.2. 2 objective stage

    After the event capture phase, then the actual target receives the event and is in the target phase

    2.2. 3 bubbling stage

    From the target element, pass up the dom tree level by level until the document object
    The following figure shows the event flow model, which is recorded as the onion model (from outside to inside, and then from inside to outside)

    Let's not talk about the historical background. Let's summarize the following points

  • By default, the browser propagates events in the form of event bubbles
  • Insert a knife through the onion, first from the outside to the inside, and then from the inside to the outside, that is, the event flow first captures the target element from the outermost document, and then bubbles to the document through the target element
  • If you want to trigger the capture phase event, you can set the third parameter to false in the method addEventListener described above

    3. Prevent event bubbling

    3.1 event.stopPropagation()

    Sometimes the parent element and its child elements are bound with the same type of events. We don't want the events to propagate upward. If the event of which element is triggered, we will execute the event processing of that element without interfering with the events of other elements.
    You need to stop the event from bubbling

    Method: event stopPropagation()

    <div id="root">
     <button id="btn">Point me</button>
    </div>
    <script>
    var root = document.getElementById("root");
    var btn = document.getElementById("btn");
    btn.addEventListener("click", function (event) { 
      event.stopPropagation();
      console.log("btn-Event trigger");
    });
    root.addEventListener("click", function () { 
      console.log("root-Event trigger");
    });
    </script>

    In the above code, the click event of root will not be triggered.

    3.2 difference between stoppropagation and stopImmediatePropagation

    Same point

    Can prevent the event from bubbling

difference

stopImmediatePropagation() prevents the event from bubbling and prevents listeners of the same event type on the element from being triggered

give an example

  1. stopPropagation can only simply prevent bubbling

    <div id="root">
    <button id="btn">Point me</button>
    </div>
    <script>
      var root = document.getElementById("root");
      var btn = document.getElementById("btn");
      btn.addEventListener("click", function (event) { 
     event.stopPropagation();
     console.log("btn-Event trigger 1");
      });
      btn.addEventListener("click", function () { 
     console.log("btn-Event trigger 2");
      });
      root.addEventListener("click", function () { 
     console.log("root-Event trigger");
      });
    </script>

  2. stopImmediatePropagation prevents the following events of the same type from being triggered

    <div id="root">
    <button id="btn">Point me</button>
    </div>
    <script>
      var root = document.getElementById("root");
      var btn = document.getElementById("btn");
      btn.addEventListener("click", function (event) { 
     event.stopImmediatePropagation();
     console.log("btn-Event trigger 1");
      });
      btn.addEventListener("click", function () { 
     console.log("btn-Event trigger 2");
      });
      root.addEventListener("click", function () { 
     console.log("root-Event trigger");
      });
    </script>

    Note that stopImmediatePropagation can only prevent subsequent events from triggering
    In the following code, only "btn event trigger 3" is not executed

    <div id="root">
    <button id="btn">Point me</button>
    </div>
    <script>
      var root = document.getElementById("root");
      var btn = document.getElementById("btn");
      btn.addEventListener("click", function () {
     console.log("btn-Event trigger 1");
      });
      btn.addEventListener("click", function (event) {
     event.stopImmediatePropagation();
     console.log("btn-Event trigger 2");
      });
      btn.addEventListener("click", function () {
     console.log("btn-Event trigger 3");
      });
      root.addEventListener("click", function () {
     console.log("root-Event trigger");
      });
    </script>

    4. Event flow practice

    <div id="root">
      <button id="btn">Point me</button>
    </div>
    <script>
      var root = document.getElementById("root");
      var btn = document.getElementById("btn");
      document.addEventListener(
     "click",
     function () {
       console.log("document-capture");
     },
     true
      );
      document.addEventListener("click", function () {
     console.log("document-Bubbling");
      });
      root.addEventListener(
     "click",
     function () {
       console.log("root-capture");
     },
     true
      );
      root.addEventListener("click", function () {
     console.log("root-Bubbling");
      });
      btn.addEventListener(
     "click",
     function () {
       console.log("btn-capture");
     },
     true
      );
      btn.addEventListener("click", function () {
     console.log("btn-Bubbling");
      });
    </script>


    finish

    If there is any mistake, please correct it. Welcome to comment and exchange, pay attention to me and only write dry goods

Topics: Javascript Front-end