About event capture and event bubbling sequence execution order

create by db on 2021-2-21 14:33:31

Recently revised in 2021-2-21 16:00:35

Idle time to have a tight mind, busy time to have leisure fun

directory

  • preface

  • The body of the

  • conclusion

preface

Returns the directory

I hear and I fogorget.

I see and I remember.

I do and I understand.

As a front-end developer, DOM is one of our most familiar partners — F11 sees it every day.

But do you really understand it? Can you describe the sequence of event capture and event bubbling?

If you can’t remember at the moment, let’s go and have a look.

The body of the

Returns the directory

The three phases of the DOM event flow

When events occur, they are propagated in a specific order between element nodes, which is called the DOM event stream

When a DOM event is fired, it doesn’t just fire once on its own object, but it goes through three different stages:

  1. Capture Phase:
  • When we do something at a node in the DOM tree (click, mouse move up, for example), an event is emitted. The event is emitted from the Window and passes through the lower nodes to the target node. The process before reaching the target node is called the Capture Phase. This event is emitted by all passing nodes. The task of the capture phase is to set up this event-passing path so that the subsequent bubble phase can follow this path back to the Window. Capture event handlers registered on the target element object itself are not called.
  1. Target Phase:
  • The target phase is when the event is continuously passed to the target node, and finally the event is triggered on the target node.
  1. Bubbling Phase:
  • Back to the root of the document from the target event location, bubbling from the inside out event object (the event binding we usually use takes advantage of the event bubbling principle)

As shown in the figure:

The sequence of event capture and event bubbling is obvious.

DOM elements bind js events:

onclick

Create an onclick event inside an HTML tag or via an assignment. Overwriting onclick overwrites the previous attribute and supports only the bubbling phase. There are no compatibility issues

Element.onclick = function(){}

Unbind event: element.onclick = null

addEventListener

Internet Explorer 8 does not support this method. It is a DOM2 method, and multiple methods can be added without being overwritten

Parameter Description:

  • Event, required. A string specifying the event name. Do not use the “on” prefix. For example, use “click” instead of “onclick”.

  • The function must be. Specify the function to execute when the event is triggered, writing only the function name without parentheses.

  • UseCapture optional. Boolean value that specifies whether the event is executed in the capture or bubble phase.

Bind events:

element.addEventListener(
  'click'.function (e) {
    e.preventDefault() // Block the default event
  },
  false
)
Copy the code

Untying events:

element.removeEventListener('click',function(){},false)

attachEvent

IE is unique, compatible with IE8 and the following versions, can add multiple event handlers, only support bubbling stage

Parameter Description:

  • event, you must. A string specifying the event name. Notice the addition of the “on” before the event, such as “onclick” and “onmouseover”, which is associated withaddEventListenerThe difference between.
  • functionThe event to bind to listens for the function. Write only the function name, without parentheses.

Bind events:

element.attachEvent('onclick'.function (e) {
  e.returnValue = false // Block the default event
})
Copy the code

Element.detachevent (“onclick”,function(){})

Code, experiment

Open the online editor –> jsbin.com/cedorat/edi…

The code is as follows:

</html>
<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <style>
    #outer {
      text-align: center;
      width: 400px;
      height: 400px;
      background-color: yellow;
      margin: 0 auto;
    }

    #middle {
      width: 250px;
      height: 250px;
      background-color: red;
      margin: 0 auto;
    }

    #inner {
      width: 100px;
      height: 100px;
      background-color: green;
      margin: 0 auto;
    }
  </style>
</head>

<body>
  <div id='outer'>
    <span>outer</span>
    <div id='middle'>
      <span>middle</span>
      <div id='inner'>
        <span>inner</span>
      </div>
    </div>
  </div>
  <script>
    // Bind all capture events and then all bubble events
    on("outer"."click", o_click_c, true);
    on("middle"."click", m_click_c, true);
    on("inner"."click", i_click_c, true);

    on("outer"."click", o_click_b, false);
    on("middle"."click", m_click_b, false);
    on("inner"."click", i_click_b, false);


    // // bind all the bubbling events and then all the capture events
    // on("outer", "click", o_click_b, false);
    // on("middle", "click", m_click_b, false);
    // on("inner", "click", i_click_b, false);

    // on("outer", "click", o_click_c, true);
    // on("middle", "click", m_click_c, true);
    // on("inner", "click", i_click_c, true);


    // Capture and bubble events one by one
    // on("outer", "click", o_click_c, true);
    // on("outer", "click", o_click_b, false);

    // on("middle", "click", m_click_c, true);
    // on("middle", "click", m_click_b, false);

    // on("inner", "click", i_click_c, true);
    // on("inner", "click", i_click_b, false);


    // Bind bubbles and capture events one by one
    // on("outer", "click", o_click_b, false);
    // on("outer", "click", o_click_c, true);

    // on("middle", "click", m_click_b, false);
    // on("middle", "click", m_click_c, true);

    // on("inner", "click", i_click_b, false);
    // on("inner", "click", i_click_c, true);


    // Select the corresponding element
    function $(element) {
      return document.getElementById(element);
    }
    // Bind method
    function on(element, event_name, handler, use_capture) {
      if (addEventListener) { // All major browsers except IE 8 and earlier
        $(element).addEventListener(event_name, handler, use_capture);
      } else { // IE 8 and earlier
        $(element).attachEvent('on'+ event_name, handler); }}function o_click_c() {
      console.log("Outer_ capture");
    }

    function m_click_c() {
      console.log("Middle_ capture")}function i_click_c() {
      console.log("Inner_ capture")}function o_click_b() {
      console.log("Outer_ bubbling")}function m_click_b() {
      console.log("Middle_ bubbling")}function i_click_b() {
      console.log("Inner_ bubbling")}</script>
</body>

</body>

</html>
Copy the code

In the code above, we define four execution sequences:

  1. Bind all capture events first and then all bubble events

  2. First bind all the bubbling events and then all the capture events

  3. Each binding captures and bubbles events

  4. Bind bubbles and capture events one by one

First bind all capture events and then all bubble events

Let’s run the first one:

  1. Click outer to print the result:
"Outer_ capture" "outer_ bubble"Copy the code
  1. Click middle to print the result:
"Outer_ capture" "MIDDLE_ capture" "MIDDLE_ bubble" "outer_ bubble"Copy the code
  1. Click inner to print the result:
"Outer_ capture" "MIDDLE_ capture" "inner_ capture ""inner_ bubble" "MIDDLE_ bubble" "outer_ bubble"Copy the code

Conclusion:

  • It is captured from the outward-in event, up to the incident element, and then bubbles from the inside out to the root node

Bind all the bubble events first and then all the capture events

Let’s run the second one first:

  1. Click outer to print the result:
"Outer_ bubble" "outer_ capture"Copy the code
  1. Click middle to print the result:
"Outer_ capture" "MIDDLE_ bubble" "MIDDLE_ capture" "outer_ bubble"Copy the code
  1. Click inner to print the result:
"Outer_ capture" "MIDDLE_ capture" "inner_ bubble ""inner_ capture" "MIDDLE_ bubble" "outer_ bubble"Copy the code

Conclusion:

  • In the capture phase, it is first captured by outside-in events, and in the bubbling phase, it is bubbled from inside out to the root node

  • The target element performs the bubbling event and then the capture event

Capture and bubble events one by one

Let’s run the third one first:

  1. Click outer to print the result:
"Outer_ capture" "outer_ bubble"Copy the code
  1. Click middle to print the result:
"Outer_ capture" "MIDDLE_ capture" "MIDDLE_ bubble" "outer_ bubble"Copy the code
  1. Click inner to print the result:
"Outer_ capture" "MIDDLE_ capture" "inner_ capture ""inner_ bubble" "MIDDLE_ bubble" "outer_ bubble"Copy the code

Conclusion:

  • As in the first case, it is captured from the outside-in event, up to the incident element, and then bubbles from the inside out to the root node

Bind bubble and capture events one by one

Let’s run the fourth one:

  1. Click outer to print the result:
"Outer_ bubble" "outer_ capture"Copy the code
  1. Click middle to print the result:
"Outer_ capture" "MIDDLE_ bubble" "MIDDLE_ capture" "outer_ bubble"Copy the code
  1. Click inner to print the result:
"Outer_ capture" "MIDDLE_ capture" "inner_ bubble ""inner_ capture" "MIDDLE_ bubble" "outer_ bubble"Copy the code

Conclusion:

Same thing as the second one

  • In the capture phase, it is first captured by outside-in events, and in the bubbling phase, it is bubbled from inside out to the root node

  • The target element performs the bubbling event and then the capture event

conclusion

Returns the directory

Event flow execution order

From the above code, we can see the sequence of event capture and event bubbling:

  1. In the capture phase, the capture event is first executed from the outside in.

  2. When an event is fired in the target phase, it is executed in the order in which the event was registered. That is, if both bubbling and capturing events are registered, they are executed in the order they are registered.

  3. In the bubbling phase, it bubbles from the inside out to the root node.

Other:

  1. Js code can only capture or bubble one of the phases (either capture or bubble)

  2. Onclick and attachevent (IE) only get the bubbling phase

  3. In real development, we rarely use event capture and focus more on event bubbling

  4. Some events do not bubble, such as onblur, onFocus, onMouseEnter, onmouseleave

  5. Bubbling of events can sometimes cause trouble, but it can be stopped by: stopPropagation()

  • StopPropagation () method: Termination events propagate further in the capture, target processing, or bubbling stages of propagation. When this method is called, the handler that handles the event on that node is called, and the event is no longer dispatched to another node.

The road ahead is long, and I see no end.

References:

  • JS bubbling and cancel the default action (default behavior) | front-end developer blog
  • JavaScript to capture and bubble | front-end development blog
  • Stage of DOM events and event capture and event bubbling successively execution order garden – AlvinWei | blog

Postscript: Hello friends, if you think this article is good, remember to give a thumbs-up or star, your thumbs-up and star is my motivation to write more and richer articles!Making the address

Document agreement



dbThe document library 由 dbusingCreative Commons Attribution – Non-commercial Use – Same way Share 4.0 International LicenseGrant permission.

Based on thegithub.com/danygitgitOn the creation of works.

Use rights other than those authorized by this License agreement may be obtained from
Creativecommons.org/licenses/by…Obtained.