1, Events
Before understanding what is the event flow in js, let's first understand what is the event flow in js. Interpretation by reference to W3c
HTML events are what happens to HTML elements When using javaScript in HTML, javaScript can deal with these events
Examples of common events:
- onClick (mouse click element)
- onmouseover (mouse in element)
- onmouseout (mouse out element)
- onkeydown (press the keyboard key)
- ...
2, Event flow
What is event and what is event flow?
Let's take it literally. We already know what the event is. What about the stream? Let's take a look at Baidu's explanation of streaming
If we connect events, can we understand the event flow as the sequence of receiving events from the page? These events connect to form a whole like a liquid, and the events in this whole have their own execution sequence, which is the event flow.
3, Event flow model
There are two more models in the event flow
- Event capture
- Event Bubbling
Here we refer to a diagram to understand the event flow model
Event Bubbling
When a node event is triggered, it will trigger events of the same type from the inner circle to the outer circle div -- > body -- > HTML -- > document to the DOM root node
Event capture
When a node event is triggered, it will trigger the same type events of its descendants from the DOM root node to the current node itself. From outer ring to inner ring document -- > HTML -- > body -- > div
4, Development history of event flow model
Event bubbling is proposed by IE, while event capture is the concept of event flow proposed by Netscape.
Later, ECMAScript integrated the two models and formulated a unified standard: first capture in bubbling
Now the integrated standard event flow has three stages:
- Event capture phase (the target does not receive events in the capture phase)
- Target phase (the execution phase of the event, which will be classified as bubbling phase)
- Event bubbling phase (event returned to Dom root node)
Tips: DOM2 level events stipulate that the target phase events will not be involved in the capture phase, but in IE9, Safari, Chrome, Firefox and opera 9 Version 5 and later will trigger the event on the target event in the capture phase
5, addEventListener()
The addEventListener() method is used to add an event handle to the specified element.
parameter | describe |
---|---|
event | Must be a string specifying the event name |
function | You must specify the function to execute when the event is triggered |
useCapture | Optional value, specifying whether the event is executed in the capture or bubbling phase; 1. true: the event handle is executed in the capture phase; 2. - false - by default, the event handle is executed in the bubbling phase |
addEventListener() captures the presentation
<div id="btn1" style="height: 150px;width: 150px;background: red;color: #fff"> btn1 <div id="btn2" style="height: 100px;width: 100px;background: green;color: #fff"> btn2 <div id="btn3" style="height: 50px;width: 50px;background: blue;color: #fff"> btn3 </div> </div> </div> <script> let btn1 = document.getElementById('btn1') let btn2 = document.getElementById('btn2') let btn3 = document.getElementById('btn3') btn1.addEventListener('click',function (){ alert('btn1') },true) btn2.addEventListener('click',function (){ alert('btn2') },true) btn3.addEventListener('click',function (){ alert('btn3') },true) </script>
When we click btn3, let's take a look at the execution of this code
When we click btn2, let's take a look at the execution of this code
Because the last parameter of addEventListener() is set to true, the whole execution process is carried out according to the capture. Start from the current Dom root node until the current node itself.
addEventListener() bubbling demo
It is the same code, but here we change the last parameter of addEventListener() to false and set the execution process to bubble.
Tips: because the last parameter of addEventListener() is false (bubbling) by default, you can write it without writing
<div id="btn1" style="height: 150px;width: 150px;background: red;color: #fff"> btn1 <div id="btn2" style="height: 100px;width: 100px;background: green;color: #fff"> btn2 <div id="btn3" style="height: 50px;width: 50px;background: blue;color: #fff">btn3</div> </div> </div> <script> let btn1 = document.getElementById('btn1') let btn2 = document.getElementById('btn2') let btn3 = document.getElementById('btn3') btn1.addEventListener('click',function (){ alert('btn1') },false) btn2.addEventListener('click',function (){ alert('btn2') },false) btn3.addEventListener('click',function (){ alert('btn3') },false)
Take a look at the implementation
It can be seen here that the execution sequence is to execute the events of the node itself first, and then execute the events of the same type of its ancestor node upward until the Dom root node.
6, stopPropagation() prevents capture
The stopPropagation() method prevents the propagation of the same event called. Propagation means bubbling up to the parent element or capturing down to the child element.
We use the stopPropagation() function on btn2
<div id="btn1" style="height: 150px;width: 150px;background: red;color: #fff"> btn1 <div id="btn2" style="height: 100px;width: 100px;background: green;color: #fff"> btn2 <div id="btn3" style="height: 50px;width: 50px;background: blue;color: #fff">btn3</div> </div> </div> <script> let btn1 = document.getElementById('btn1') let btn2 = document.getElementById('btn2') let btn3 = document.getElementById('btn3') btn1.addEventListener('click',function (){ alert('btn1') },false) btn2.addEventListener('click',function (event){ event.stopPropagation() alert('btn2') },false) btn3.addEventListener('click',function (){ alert('btn3') },false) </script>
Take a look at the implementation
We can see that when we click btn3, it bubbles and terminates after executing to btn2
7, Application of event flow model
Event delegation, also known as event agent, refers to using the event bubbling principle to add events to the outer parent container. If the inner child element has a click event, it will bubble to the parent container. This is event delegation. In short, child elements delegate their parent to execute events.
Where is the application scenario of this situation? for instance:
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
We now have such a list. I want to listen to all < li > tags. I only list five < li > tags here, but in actual business, there may be thousands of < li > tags circulating here. If we bind events to each < li >, it will greatly affect the page performance. At this time, we can use event delegation for optimization.
let ulDom = document.getElementsByTagName('ul') ulDom[0].addEventListener('click', function(event){ alert(event.target.innerHTML) })
Let's take a look at the implementation
As you can see, we have added click events to every < li > tag through event delegation
Advantages of event delegation
Let's summarize the optimization of event delegation:
- Improve performance: each function will occupy memory space. Just add an event handler to proxy all events, which will occupy less memory space.
- Dynamic listening: use event delegation to automatically bind dynamically added elements, that is, new nodes do not need to be actively added, but can also have the same events as other elements.