Cause:
1, this is the front of the classic interview questions, to find a job to see the small partner is still helpful;
2. In fact, I have not been able to understand. I wrote this for a memo and for reference for other small partners who know it but do not know why.
Summary:
So what is event delegation? It is also known as the event proxy. In advanced JavaScript programming, the event delegate manages all events of a certain type by specifying only one event handler. So what does that mean? Online you recognize speaking event delegation basically all use the same example, is take the express to explain this phenomenon, I carefully ponder for a moment, this example is appropriate, I will not to think of other examples to explain, we are, I picked over, all seriously what understand the event delegation is a principle:
Three colleagues are expected to receive express delivery on Monday. In order to sign for express delivery, there are two ways: one is three people waiting for express delivery in front of the company; Second, entrust the reception desk MM to sign for it. In reality, most of us use the delegation-based approach (and companies don’t tolerate so many employees standing at the door waiting for delivery). After receiving the express, the receptionist will judge who the recipient is, and then sign for it according to the recipient’s requirements, and even pay for it. Another advantage of this scheme is that even if there are new employees in the company (no matter how many), the receptionist will verify and sign for the delivery after receiving it.
In fact, there are two meanings:
First, now the colleague of the delegate front desk can sign for it, that is, the existing DOM node in the program has events;
Second, new employees can also be signed by the foreground MM, that is, the NEWLY added DOM node in the program also has events.
Why use event delegates:
In general, the DOM needs to have an event handler, so we’ll just give it an event handler, but what about a lot of DOM that needs to have an event handler? For example, if we have 100 Li’s, each of which has the same click event, maybe we’re going to use a for loop to go through all of them and add events to them, what’s the effect of doing that?
In JavaScript, the number of event handlers added to the page is directly related to the overall performance of the page, because it requires constant interaction with DOM nodes. The more times the DOM is accessed, the more times the browser redraws and rearranges, which will extend the interaction ready time of the whole page. This is why one of the main ideas of performance optimization is to reduce DOM manipulation; If you want to use event delegate, you will put all the operations in THE JS program, and the operation with the DOM only needs to interact once, which can greatly reduce the interaction with the DOM, improve performance;
Each function is an object, the object will use memory, object, the more the greater the memory usage rate, nature is the worse performance (not enough memory to use, is called flints, haha), such as the 100 li, would take 100 memory space, and if it was 1000, 10000, that can only say that ha ha, if use event delegation, Then we can only operate on its parent (if there is only one parent) this object, so we need a memory space is enough, is not a lot of savings, natural performance will be better.
How event delegation works:
Event delegation is implemented using the event bubble principle. What is event bubble? For example, if you have a tree of nodes on your page, div>ul>li>a; For example, if we add a click event to the innermost div, then the event will be executed in the order a>li>ul>div. If we add a click event to the outermost div, then ul, li, and a will bubble up to the outermost div. So they all get fired, so this is event delegate, delegating to their parent to execute the event on their behalf.
How to implement event delegate:
This is the core of this article. Before introducing the method of event delegate, let’s look at an example of a general method:
Child nodes perform the same function:
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
Copy the code
Click li, and 123 pops up:
window.onload = function(){
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
for(var i=0; i<aLi.length; i++){ aLi[i].onclick =function(){ alert(123); }}}Copy the code
The code above is very simple, I believe that many people do this, let’s see how many times the DOM operation, first to find ul, and then through the li, and then click on li, again to find the target li, to perform the final operation, each click on the li to find the li;
So what if we do it as event delegate?
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){ alert(123); }}Copy the code
Here with the parent ul do event processing, due to the principle of bubble, when li was click events will bubble to the ul, click event because ul, so events can trigger, of course, here when clicking the ul also triggers, so the question becomes, ‘if I want to make the effect of the event agency like directly to the node event effect to do, For example, only click li to trigger, not afraid, we have a trick:
The Event object provides a property called target that returns the target node of the Event, which we call the Event source. In other words, target can be represented as the DOM that the current Event operates on, but not the actual DOM. Of course, this is compatible. NodeName = nodeName = nodeName = nodeName = nodeName = nodeName = nodeName = nodeName = nodeName = nodeName
window.onload = function(){var oUl = document.getelementById ();"ul1"); oUl.onclick =function(ev) {var ev = ev | | window. The event; var target = ev.target || ev.srcElement;if(target.nodeName.toLowerCase() == 'li') {alert (123); Alert (target. InnerHTML); }}}Copy the code
In this way, only clicking li will trigger an event, and only one DOM operation will be performed at a time. If the number of Li is large, it will greatly reduce the DOM operation and optimize the performance.
The example above shows that li performs the same effect. If each li is clicked differently, is event delegate still useful?
<div id="box">
<input type="button" id="add" value="Add" />
<input type="button" id="remove" value="Delete" />
<input type="button" id="move" value="Mobile" />
<input type="button" id="select" value="Choice" />
</div>
Copy the code
window.onload = function(){
var Add = document.getElementById("add");
var Remove = document.getElementById("remove");
var Move = document.getElementById("move");
var Select = document.getElementById("select");
Add.onclick = function(){
alert('add');
};
Remove.onclick = function(){
alert('delete');
};
Move.onclick = function(){
alert('mobile');
};
Select.onclick = function(){
alert('choose'); }}Copy the code
I’m not going to go through what I did above, it’s very simple, 4 buttons, click on each one to do something different, so you need at least 4 DOM operations, so if you use event delegate, can you optimize that?
window.onload = function(){
var oBox = document.getElementById("box");
oBox.onclick = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLocaleLowerCase() == 'input'){
switch(target.id){
case 'add' :
alert('add');
break;
case 'remove' :
alert('delete');
break;
case 'move' :
alert('mobile');
break;
case 'select' :
alert('choose');
break; }}}}Copy the code
So if you use event delegate you can do all of this with just one DOM operation, so it’s definitely a little bit better than what we’re talking about right now we’re talking about an existing DOM node that has been loaded by document, so if it’s a new node, will that new node have an event? In other words, when a new employee comes in, does he get the delivery? Take a look at the normal way to add a node:
<input type="button" name="" id="btn" value="Add" />
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
Copy the code
Now it is possible to add a child node of li to ul by clicking the button to add a child node of Li to ul
window.onload = function(){
var oBtn = document.getElementById("btn");
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li'); var num = 4; // The mouse turns red when moving in and white when moving outfor(var i=0; i<aLi.length; i++){ aLi[i].onmouseover =function(){
this.style.background = 'red';
};
aLi[i].onmouseout = function(){
this.style.background = '#fff'; } // Add a new node obtn.onclick =function(){
num++;
var oLi = document.createElement('li');
oLi.innerHTML = 111*num;
oUl.appendChild(oLi);
};
}
Copy the code
This is the general way to do it, but you’ll notice that the new Li has no events, which means that when we add children, we don’t add events together, which is not what we want, so how do we do that? A general solution would be to wrap the for loop in a function named mHover, as follows:
window.onload = function(){
var oBtn = document.getElementById("btn");
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
var num = 4;
function mHover() {// The mouse turns red when moving in and white when moving outfor(var i=0; i<aLi.length; i++){ aLi[i].onmouseover =function(){
this.style.background = 'red';
};
aLi[i].onmouseout = function(){
this.style.background = '#fff'; } } } mHover (); // Add a new node obtn.onclick =function(){
num++;
var oLi = document.createElement('li');
oLi.innerHTML = 111*num;
oUl.appendChild(oLi);
mHover ();
};
}
Copy the code
Although the function is implemented, it looks good, but in fact it is an added DOM operation, in terms of performance optimization is not desirable, so there is an event delegate way, can do optimization?
window.onload = function(){
var oBtn = document.getElementById("btn");
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li'); var num = 4; // Event delegate, adding child elements that also have event oUl. Onmouseover =function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = "red"; }}; oUl.onmouseout =function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = "#fff"; }}; // Add a new node obtn.onclick =function(){
num++;
var oLi = document.createElement('li');
oLi.innerHTML = 111*num;
oUl.appendChild(oLi);
};
}
Copy the code
See, the above is the way to entrust with events, the newly added effect of child elements with the event, we can find that when using event delegation, don’t need to traverse the element’s child nodes, only need to add events to the parent element, the others are all in js, so can greatly reduce the dom manipulation, This is the essence of event delegation.
< span style = “box-sizing: border-box; color: RGB (74, 74, 74); line-height: 20px; font-size: 14px! Important; word-break: break-all;”
<ul id="test">
<li>
<p>11111111111</p>
</li>
<li>
<div>
22222222
</div>
</li>
<li>
<span>3333333333</span>
</li>
<li>4444444</li>
</ul>
Copy the code
Click li, the event object must be the current clicked object. How to specify the event object on li, I directly give the solution below:
var oUl = document.getElementById('test');
oUl.addEventListener('click'.function(ev){
var target = ev.target;
while(target ! == oUl ){if(target.tagName.toLowerCase() == 'li'){
console.log('li click~');
break; } target = target.parentNode; }})Copy the code
The core code is the while loop, which is actually a recursive call, or you can write a function, and you call it recursively, and you bubble it, and you bubble it out, until you get to currentTarget, when the currentTarget is li, then you execute the event, and then you terminate the loop, Yeah, no problem!
Conclusion:
What kinds of events can use event delegates and what kinds of events can’t use event delegates?
Events that use event delegates: click, mouseDown, mouseup, keyDown, keyUp, keyPress.
It is worth noting that mouseover and Mouseout do have event bubbles, but they require special attention because their positions are often calculated and are not easy to handle.
Mousemove, for example, has to calculate its position every time, which is very difficult to control. In other words, focus, blur, etc., it doesn’t use the bubbling feature itself, so you can’t use event delegate.
Ok, that’s all for today, next time I want to introduce the event binding, welcome to pay attention and read, the above is purely personal opinion, if there is any wrong place, hope to correct, thank you! Transfer: www.cnblogs.com/liugang-vip…