define

Event bubbling and capture were developed by Microsoft and Netscape respectively to solve the problem of event flow in a page, that is, the order in which events occur. Here’s an example:

<div id="a1">
    <p id="a2"></p>
</div>
Copy the code

If I mount a click handler on A2 and click A2 on the page, will the event registered on A1 or A2 be fired first?

The event bubbling

Microsoft’s IE presents a bubbling stream of events. What do I mean by event bubbling? We can think of it as a bubble at the bottom of the water. The bubble in the water will continue to rise until it comes to the surface. Event bubbling is something like this bottom-up process, where the event starts at the innermost element and goes all the way up to document. That is, assuming we clicked a2 in the previous example, events would occur in the following order: P -> div -> body -> HTML -> document

Event capture

Netscape, on the other hand, offers a stream of events captured by events. If an event bubbles like a bubble rising from the bottom, event capture is like a rock thrown into the bottom. Instead of event bubbling, events are captured from the outermost to the innermost elements: Document -> HTML -> body -> div -> P

addEventListener

Notes on MDN:

EventTarget. AddEventListener (event, function, useCapture) methods will specify the listeners registered on the EventTarget, when the object trigger event is specified, the specified callback function will be executed.

This method takes three arguments. The first parameter is the event to mount, such as click; The second parameter is the function corresponding to the event, such as changing the color of a div; The third parameter takes a Boolean type. When false, events are processed in the event bubble order. If true is entered, events are processed in the order in which they are captured. The default value for the third parameter is false.

False — > Event bubble (default) true — > event capture

Example of event bubbling

<div id="a1">a1
    <p id="a2">a2</p>
</div>
<script>
a1.addEventListener("click".function(e){
    console.log('a1 bubble')},false)
a2.addEventListener("click".function(e){
    console.log('a2' bubble.)},false)
</script>
Copy the code

Result: A1 bubbles on the console when clicking A1; When clicking A2, the console bubbles A2 and A1

Event capture example

<div id="a1">a1
    <p id="a2">a2</p>
</div>
<script>
a1.addEventListener("click".function(e){
    console.log('a1 capture')},true)
a2.addEventListener("click".function(e){
    console.log('a2 capture')},true)
</script>
Copy the code

Result: A1 capture appears on the console when a1 is clicked; When you click a2, the console appears a1 capture A2 capture

There is event bubbling and event catching at the same time

Let’s take a look at the example and the result:

<div id="a1">a1
    <div id="a2">a2</div>
</div>
<script>
a1.addEventListener("click".function(e){
        console.log("A1" bubble.);         
},false);
a2.addEventListener("click".function(e){
        console.log("A2 bubble");
},false);
        
a1.addEventListener("click".function(e){
        console.log("A1 capture");
},true);
        
a2.addEventListener("click".function(e){
        console.log("A2 capture");
},true);
</script>
Copy the code

Result: Click A1, a1 bubbles appear in the console, a2 capture click A2, a1 capture A2 bubbles appear in the console successively

According to the results, we can conclude the process:

1. Proceed from document to capture the clicked node, and execute event 2 as soon as the registered capture event is encountered. Execute the registered event upon reaching the clicked node 3. After executing the event on the clicked node, bubble forward and execute the event immediately upon encountering the registered bubbling event

conclusion

1. For non-clicked nodes, capture first and then bubble. 2. For clicked nodes, the first registered events are executed sequentially

Practical application: Event broker

Taking advantage of the nature of this event flow, we can use the event broker approach.

<ul id="color">
    <li>red</li>
    <li>orange</li>
    <li>yellow</li>
    <li>green</li>
    <li>blue</li>
    <li>purple</li>
</ul>
Copy the code

If we had to click on the Li element in the page and output the color, we might have used a loop, but the downside of using a loop is that each time the loop creates a new function to bind the event, which can be costly in performance. If we use the event broker method, we can also use the characteristics of event flow to bind only one event handler function:

    color.addEventListener("click",(e)=>{
    let a = e.target
    if(a.nodeName === li){
        console.log("The color is" + a.innerHTML)
    }
    },false)
Copy the code


If you find my articles useful, please like them and follow them. Also, please visit my personal blog github.com/BokFang