A DOM event is an action performed by the user or the browser itself. It is a moment of interaction between a document or the browser, such as a click button, where click is the event name

1. The flow of events

When we click a button on a page, which element on the page triggers the click, does it happen on this element, or does the element’s parent also trigger the click?

This involves the flow of events. Event capture and event bubbling were developed by Microsoft and Netscape, respectively, to solve the problem of event flow (the order in which events occur) in a page.

2. Event capture

Netscape came up with an event stream called Event Capturing. Events occur from the outside to the inside, up to the most concrete element.

So under the concept of event capture the order in which click events occur on TD elements should be

window -> document -> html -> body -> table -> tbody -> tr -> td
Copy the code

3. Events bubble up

Microsoft has come up with a stream of events called Event Bubbling. Event bubbling can be likened to dropping a stone into water and bubbles will continue to rise from the bottom to the surface. That is, events start from the inside out and propagate up to the root object.

So under the concept of event bubbling the order of click events on td elements should be

td -> tr -> tbody -> table -> body -> html -> document -> window
Copy the code

While Microsoft and Netscape were at it, the W3C, as a mediator, came up with a common standard — capture now, bubble later

The third parameter to addEventListener is for bubbling and capturing

element.addEventListener(event, function.useCapture// The first argument is the event to bind to. // The second argument is the function to execute after the event is triggered. // The third argument is the event stream to usefalse, means that the event handler function is called during the event bubbling phase,trueCall the event handler during the capture phaseCopy the code

When event capture and event bubbling exist together, how does the event fire?

The DOM node that is clicked is the target node.

  • For non-target nodes, capture is performed before bubbling
  • For the target node, the event is executed first and registered first, whether bubbling or capturing

4. Event delegation

Since events propagate up to the parent node during the bubbling phase, you can define the listener function of the child node on the parent node and let the listener function of the parent node process events of multiple child elements uniformly. This approach is called event delegation

Advantages of event delegation

  1. You can save a lot of memory and reduce event registration, such as proxying all li’s click events on UL is great
<ul id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>.<li>item n</li>
</ul>
Copy the code

As the code above shows, if you bind a function to each li item, it is very expensive to use memory, so a better solution is to bind the li element’s click event to its parent ul, and then execute the event to match the target element

  1. You can add a child object without binding it again (dynamically binding events)
<ul id="test">
  <li id="li1">item 1</li>
  <li id="li2">item 2</li>
  <li id="li3">item 3</li>
</ul>
Copy the code

Traditionally, the above code would add three event handlers as follows

let item1 = document.getElementById("li1");
let item2 = document.getElementById("li2");
let item3 = document.getElementById("li3");
 
item1.onclick = function() {
    location.href = "http://www.baidu.com";
};
item2.onclick = function() {
    document.title = "Event delegation";
};
item3.onclick = function() {
    alert("hi");
};
Copy the code

If you did this for all clickable elements in a complex Web application, the result would be untold code for adding event handlers. At this point, you can use event delegation techniques to solve this problem.

let item1 = document.getElementById("li1");
let item2 = document.getElementById("li2");
let item3 = document.getElementById("li3");
 
document.addEventListener("click".function (e) {
    let t = e.target;
    switch (t.id) {
     case "li1":
           document.title = "Event delegation";
           break;
     case "li2":
           location.href = "http://www.baidu.com";
           break;
      case "li3": 
           alert("hi");
           break; }})Copy the code

When you use event delegation, you don’t necessarily want to delegate events as close to the top as possible. The bubbling process of events also takes time, and the closer you get to the top, the longer the “event propagation chain” of events, the more time it takes. If the DOM is deeply nested, events bubbling through a large number of ancestor elements can result in a performance penalty.