Event delegation or event proxy details in js
This article was reproduced from ( http://www.cnblogs.com/liugang-vip/p/5616484.html)
Causes:
1. This is a classic type of front-end interview. It is helpful to go to a small partner to find a job.
2. Actually, I have never understood it. Writing this is for the purpose of remembering, and it is for the reference of other unknown partners.
Summary:
So what is event delegation?It also has a name called event proxy, which JavaScript advanced programming says: Event delegates use event bubbles to manage all events of a certain type by specifying only one event handler.So what does this mean?Every bull on the Internet has basically used the same example to explain the entrustment of events, that is, to take a courier to explain this phenomenon. I have carefully guessed that this example is really appropriate, I do not want to think of other examples to explain, borrow flowers and donate Buddhas, I pick them up, you carefully understand what the entrustment of events is.What principle:
Three colleagues expect to receive the courier on Monday.There are two ways to sign and receive the courier: one is for three people to wait for the courier at the company gate; the other is to entrust the front MM to sign and receive for them.In reality, we mostly use a delegated scheme (companies will not tolerate so many employees standing at the door waiting for a courier).When Front Desk MM receives the courier, she will determine who the recipient is, and then sign and receive it at the recipient's request, or even pay for it on her behalf.Another advantage of this scheme is that even if a new employee (no matter how many) arrives in the company, the front desk MM will check and sign the delivery to the new employee.
There are actually two more meanings here:
First, colleagues who delegate to the front desk can now sign in on their behalf, that is, existing dom nodes in the program have events;
Second, new employees can also be signed by the foreground MM, that is, new dom nodes added in the program are also events.
Why delegate with events:
Generally speaking, a dom needs an event handler. We all set up event handlers for it directly. So what if there are so many DOMS that need to add event handlers?For example, if we have 100 li, each of which has the same click click event, maybe we will use the for loop to iterate through all the Li and then add events to them. What happens when we do this?
In JavaScript, the number of event handlers added to a page is directly related to the overall performance of the page, because the more you need to interact with the DOM node, the more times you access the dom, the more browser redraws and rearrangements will occur, and the longer the interaction ready time for the entire page will be, which isOne of the main ideas of performance optimization is to reduce the number of DOM operations; if you delegate with events, all operations will be placed in the js program, and the operations with the DOM only need to interact once, which can greatly reduce the number of interactions with the DOM and improve performance;
Each function is an object, the object will occupy memory. The more objects there are, the more memory will occupy, the worse the natural performance will be (memory is not enough, is hard injury, haha). For example, the 100 li above will occupy 100 memory space. If 1000, 10000, it can only say hah, if you useEvent delegation allows us to operate on only one object, its parent (if there is only one parent), so we need one memory space. If we save a lot, natural performance will be better.
The principle of event delegation:
Event delegation is achieved by using the bubbling principle of events. What is event bubbling?For example, if you add a click click event to the innermost a, then the event will execute one level at a time, executing in the order a>li>ul>div. With such a mechanism, IWhen they add a click event to the outermost div, ul, li, a inside will bubble onto the outermost div when they do a click event, so it will trigger. This is event delegation, which delegates their parent to execute the event on behalf of them.
How event delegates are implemented:
Finally, at the core of this article, Haha, before we introduce the method of event delegation, let's take a look at an example of the general method:
Child nodes perform the same functions:
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
The function is to click on li and pop up 123:
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);
}
}
}
The above code means very simple, I believe many people do this. Let's see how many dom operations we have, first find ul, then traverse li, then click li, and then find the location of the target Li to perform the last operation, once for each click.
So what happens when we delegate events?
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){
alert(123);
}
}
Here we use the parent ul to do things. When li is clicked, due to the bubbling principle, the event will bubbles onto ul, because UL has a click event, so the event will trigger. Of course, when you click UL here, it will also trigger, so the problem is, if I want the effect of event agent to follow that of directly to the nodeWhat can we do about the same effect of an event, for example, only clicking on li will trigger it. Don't be afraid, we have great tricks:
The Event object provides an attribute called target, which returns the target node of the event. We become the source of the event, that is, the target can be represented as the dom of the current event operation, but it is not really the dom of the event operation. Of course, this is compatible. The standard browser uses ev.target, and the IE browser uses event.srcElement.Here we use nodeName to get the exact label name. This returns an uppercase one. We need to convert it to lowercase before making a comparison (habitual problem):
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}
In this way, only a single click on the li triggers events, and only one dom operation is executed at a time. If there are a large number of lis, the operation of the dom will be greatly reduced, and the optimized performance is conceivable!
The example above shows that the same effect is achieved by lis. If each LIS is clicked on with different effects, is event delegation useful?
<div id="box">
<input type="button" id="add" value="Add to" />
<input type="button" id="remove" value="delete" />
<input type="button" id="move" value="move" />
<input type="button" id="select" value="Choice" />
</div>
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 to');
};
Remove.onclick = function(){
alert('delete');
};
Move.onclick = function(){
alert('move');
};
Select.onclick = function(){
alert('Choice');
}
}
I won't say much about the above effect. It's very simple, four buttons, click each to do a different operation, then at least four dom operations are needed. If you delegate events, can you optimize them?
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 to');
break;
case 'remove' :
alert('delete');
break;
case 'move' :
alert('move');
break;
case 'select' :
alert('Choice');
break;
}
}
}
}
Event delegation can accomplish all the effects in only one dom operation, which is certainly better than the above performance
Now we are all talking about the operations under the existing dom node that the document loads, so if it is a new node, will there be events on the new node?That is, if a new employee comes, can he receive the courier?
Take a look at the normal way to add nodes:
<input type="button" name="" id="btn" value="Add to" />
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
Now move in li, Li turns red, Li goes white, so this effect, then click the button, you can add a Li child node to ul
window.onload = function(){
var oBtn = document.getElementById("btn");
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
var num = 4;
//Mouse moves in red, out white
for(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);
};
}
This is normal practice, but you will find that there are no events for the newly added li s, which means that when adding child nodes, events were not added together. This is not what we want. What can we do?The general solution would be to wrap the for loop in a function called 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 () {
//Mouse moves in red, out white
for(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 ();
};
}
Although the function is implemented and looks good, there is no doubt that another dom operation has been added, which is not advisable in terms of optimizing performance. Can there be an event delegation way to optimize?
window.onload = function(){
var oBtn = document.getElementById("btn");
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
var num = 4;
//Event delegation, adding child elements also have events
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);
};
}
Look, above is the way of event delegation. The newly added child elements have the effect of event. We can see that when delegating with event, there is no need to traverse the child nodes of the element at all. Just add events to the parent element. The others are executed in js, which can be greatly reduced.Less dom of DOM is the essence of event delegation.