“This is the ninth day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Event delegation
Event delegation refers to borrowing event bubbling or event capturing mechanisms, so that if we have many elements that are handled in a similar way, we don’t have to assign an event handler to each element — instead, we place individual handlers on their common ancestor.
This article is following the JS event and event flow model after the article, which introduces the event bubbling and capture mechanism, do not understand the students can see.
Take a common example: for example, one way is for students in a dormitory to get the express delivered at the same time. Another way is to entrust the matter to the dormitory leader and ask someone to go out and get all the express delivered, and then distribute it to each student according to the recipients. Here, taking delivery is an event, and each student refers to the DOM element that needs to respond to the event, while the dormitory leader who goes out to get the delivery is the agent element, so the element that really binds the event is this element. The process of delivering the delivery according to the recipient is in the event execution. You need to determine which or more of the proxied elements the currently responding event should match.
Propagation between child elements and parent elements after an event is triggered. This spread is divided into three stages. (1) Capture phase: the transmission from the Window object to the target node (upper to bottom) is called capture phase, and the capture phase will not respond to any events; (3) Bubbling phase: conduction from the target node back to the Window object (from bottom to top), called the bubbling phase. Event broker is to bind the events that the inner layer needs to respond to to the outer layer by the mechanism of event bubbling.
Add click events for each li before using the event broker:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
Copy the code
const ul = document.querySelector('ul');
// Get all li's
const lis = document.querySelectorAll('li');
// Bind events one by one
lis.forEach(li= > {
li.addEventListener('click'.function (event){
alert(`The ${this.innerText}Being clicked);
});
});
Copy the code
We need to get all of the Li’s and then add events to all of its elements. This has two drawbacks:
- The newly added Li tag needs to bind events to it again
let newLi = document.createElement("li"); newLi.innerText = '5'; ul.appendChild(newLi); // Clicking 5 will not trigger the event Copy the code
- Each LI tag is bound to a separate event
When we use the idea of an event broker to add event handlers to it:
const ul = document.querySelector('ul');
// The event is bound to its common ancestor ul
ul.addEventListener('click'.function (event){
// this is ul, event. Target is li
alert(`${event.target.innerText}Being clicked);
})
let newLi = document.createElement("li");
newLi.innerText = '5';
ul.appendChild(newLi);
Copy the code
There is one more problem: clicking on other ul elements will trigger events, but we only want to trigger events when clicking on the first layer li tag under UL. Other tags will not trigger when clicked.
The tag type of event.target can be used to determine whether the clicked tag is li, and then whether the parent element is UL to determine whether it is the first li tag under UL.
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li><div>4</div></li>
<span>5</span>
<div>6</div>
</ul>
<script>
const ul = document.querySelector('ul');
ul.addEventListener('click'.function (event){
const target = event.target
// The tag is li and the parent element is ul
if(target.tagName === 'LI' && target.parentNode === this){
alert(`${target.innerText}Being clicked); }});</script>
Copy the code
Now we have solved the problem, but we have a new problem that when we click 4, the event will not be triggered. The reason is that 4 is wrapped in a div tag, so this time the target div is not Li. But logically we also need to handle the event handler for hitting Li (because of the bubbling mechanism)
We can do this by getting the target’s ancestor node. If we want the proxied event’s Li to be its ancestor, then we need to execute the handler
const ul = document.querySelector('ul');
ul.addEventListener('click'.function (event){
let target = event.target
// Get the ancestor of the clicked node until its parent is ul
while(target && target.parentNode ! = =this){
target = target.parentNode;
}
if(target.tagName === 'LI' && target.parentNode === this){
alert(`${target.innerText}Being clicked); }});Copy the code
Such a simple version of the event broker is implemented, he has what benefits:
- You only need to bind one event to ul and use less memory
- You can listen for events for dynamically added elements without having to rebind each time you add an element.
Event delegation
Event delegate is a name, for example in the example above, ul is the li delegate for the Click event, which is called the event delegate. You can also say that Li delegates the Click event to UL, which is called event delegation.
So when an interviewer asks you the difference between event delegation and event agency, don’t be fooled. The two are the same thing.