The event delegate or event agent in JS

Source: Internet
Author: User
Tags tag name

Overview:

What do you call an event delegate? It also has a name called Event Broker, JavaScript Advanced Programming: Event delegation is to use event bubbling, specify only one event handler, you can manage all the events of a certain type. So what does that mean? On the Internet, you are talking about the event commissioned by the same example, is to take express to explain this phenomenon, I carefully try to figure out, this example is really appropriate, I do not think of other examples to explain, jiehuaxianfo, I picked up, we carefully understand the event entrusted to the end is a what principle:

Three colleagues are expected to receive a courier in Monday. For the Signature Express, there are two ways: one is three people at the door of the company and other courier, the second is entrusted to the front desk mm for sign. In reality, most of US use commissioned programs (the company will not tolerate so many employees standing at the door to wait for courier). The front desk mm received the courier, she will determine who the recipient, and then according to the recipient's request for sign, or even on behalf of payment. This solution also has an advantage, that is, even if the company's new employees (regardless of how much), the front desk mm will be sent to the new staff after The courier to verify and sign on behalf of.

There are actually 2 layers of meaning here:

First, now entrusted to the front desk colleague can sign on behalf of, that is, the existing DOM node in the program has events;

Second, the new staff can also be the foreground mm on behalf of the sign, that is, the new DOM node added in the program is also an event.

Why Use event delegates:

In general, Dom needs to have an event handler, we will directly set it to the event handler, that is, if a lot of DOM needs to add event processing? For example, we have 100 Li, each Li has the same click-click event, maybe we will use a For loop method to traverse all the Li, and then add events to them, so what is the impact of this?

In JavaScript, the number of event handlers added to the page is directly related to the overall performance of the page, because the need to constantly interact with the DOM nodes, the more times the DOM is accessed, the more times the browser redraws and reflow, the longer the interactive ready time for the entire page, This is one of the main ideas of performance optimization is to reduce the reason for DOM operation, if you want to use event delegation, will all the operations into the JS program, and DOM operation only need to interact once, so that can greatly reduce the number of interactions with the DOM, improve performance;

Each function is an object, the object will occupy memory, the more objects, the higher the memory occupancy rate, the more natural performance is worse (insufficient memory, is the mishap, haha), such as the above 100 Li, will occupy 100 memory space, if it is 1000, 10,000, it can only say hehe, If the event is delegated, then we can only manipulate its parent (if there is only one parent), so that we need a memory space is enough, is not a lot of savings, natural performance will be better.

The principle of event delegation:

Event delegates are implemented using the bubbling principle of events, what is event bubbling? It is the event that starts with the deepest node and then propagates the event up and down, for example: There is a node tree on the page,div>ul>li>a; for example, to add a click Click event to the innermost a, then the event will be executed one layer at a level, and the order of execution a> Li>ul>div, there is such a mechanism, then we give the outermost div plus click events, then the inside of the Ul,li,a do click events, will bubble to the outermost div, so it will trigger, this is the event delegate, delegate their parents to execute the event on their behalf.

How the event delegate is implemented:

Finally to the core of this article, Haha, before introducing the method of event delegation, we first look at a general Method Example:

Child nodes implement the same functionality:

<ul id= "UL1" >    <li>111</li>    <li>222</li>    <li>333</li>    <li>444</li></ul>

The implementation function is to click on Li, which pops 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 meaning of the above code is very simple, I believe many people are so realized, we see how many times the DOM operation, first to find UL, and then Traverse Li, and then click on Li, but also find the location of the target Li, in order to perform the final operation, each click to find Li;

So what happens if we do it in the same way as the event delegate?

Window.onload = function () {    var Oul = document.getElementById ("Ul1");   Oul.onclick = function () {        alert (123);    }}

Here with the parent UL do event processing, when Li was clicked, due to the bubbling principle, the event will bubble to UL, because there is a click on the UL event, so the event will trigger, of course, here when click on the UL, it will trigger, then the problem is coming, If I want the effect of the event agent to be the same as the event directly to the node, for example, only click on Li to trigger, not afraid, we have a trick:

The event object provides a property called Target, which can return the destination 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 not actually manipulating the DOM, of course, this is compatible, Standard browser with Ev.target,ie browser with Event.srcelement, at this time just get the position of the current node, do not know what node name, here we use nodename to get exactly what tag name, this return is a uppercase, we need to turn to lowercase to do comparison (habit 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 click Li will trigger the event, and only one time DOM operation, if the number of Li, will greatly reduce the operation of the DOM, optimize the performance imaginable!

The above example is that Li operation is the same effect, if each Li is clicked on the effect is not the same, then use event delegate also useful?

<div id= "box" >        <input type= "button" id= "Add" value= "adding"/>        <input type= "button" id= "Remove" value= "Delete"/>        <input type= "button" id= "Move" value= "move"/>        <input type= "button" id= "select" value= "Select"/>    </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 ');            };            Remove.onclick = function () {                alert (' delete ');            };            Move.onclick = function () {                alert (' move ');            };            Select.onclick = function () {                alert (' select ');            }                    }

The above implementation of the effect I will not say, very simple, 4 buttons, click on each to do a different operation, then at least 4 times the DOM operation, if the event delegate, can be optimized?

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 (' move ');                            break;                        Case ' SELECT ':                            alert (' select ');                            Break;}}}}                    

With event delegation, you can do all the work with just one DOM operation, which is definitely better than the performance above.

Now it's all about the operation under the existing DOM node that the document is loaded with, so what if it's a new node, what happens to the new node? In other words, 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"/>    <ul id= "UL1" >        <li>111</li>        <li>222</li>        <li>333</li>        <li>444</li>    </ul>

Now is the move into Li,li red, move out Li,li white, such an effect, and then click the button, you can add an 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 move into red, move out to 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 new node            Obtn.onclick = function () {                num++;                var oLi = document.createelement (' li ');                oli.innerhtml = 111*num;                Oul.appendchild (oLi);}            ;        }

This is the general practice, but you will find that the new Li is no event, stating that when adding child nodes, events are not added together, this is not the result we want, how to do it? The general solution would be to wrap the for loop with 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 () {                //mouse move in red, move out to 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 new node            Obtn.onclick = function () {                num++;                var oLi = document.createelement (' li ');                oli.innerhtml = 111*num;                Oul.appendchild (oLi);                Mhover ();            };        }

Although the function realized, looked very good, but in fact, it is undoubtedly added a DOM operation, in the optimization of performance is not desirable, then there is the way of event delegation can be optimized?

Window.onload = function () {var obtn = document.getElementById ("btn");            var Oul = document.getElementById ("Ul1");            var aLi = oul.getelementsbytagname (' li ');                        var num = 4;                Event delegate, added child element also has 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 new node Obtn.onclick = function () {num++;  var oLi = document.createelement (' li ');              oli.innerhtml = 111*num;            Oul.appendchild (OLi);        }; }

See, the above is the way of the event delegate, the newly added child element is with the event effect, we can find that when the event delegate, there is no need to go through the elements of the child nodes, only need to add events to the parent element, the other is in the execution of JS, which can greatly reduce the DOM operation, This is where the essence of the event delegation is.

--------------------------------------------------Gorgeous split-line------------------------------------------------------- ------------------------------------------------------------

First of all, thank you at the vast Earth NV question, ask the question is very good!??????

His question is:

Now give a scene ul > li > Div > P,div occupy full div, or to UL binding time, need to judge whether the click is Li (assuming that the structure of Li is not fixed), So E.target could be p, or Div, what would you do with it?

Well, let's recreate the scene he gave us now.

<ul id= "Test" >        <li>            <p>11111111111</p>        </li>        <li>            < div>                22222222            </div>        </li>        <li>            <span>3333333333</span>        </li>        <li>4444444</li>    </ul>

As listed above, there are 4 Li, the contents are different, click the Li,event object is definitely the current click on the object, how to specify to Li, below I directly to the solution:

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;        }    })

The core code is a while loop part, is actually a recursive call, you can also write a function, using recursive method to call, while using the principle of bubbling, bubbling out from inside, know Currenttarget, when the current target is Li, You can execute the corresponding event, then terminate the loop, yes, no problem!

Here do not see the effect, you can copy the past to run a bit!

--------------------------------------------------------------------Gorgeous split-line----------------------------------------------- -----------------

The event delegate or event agent in JS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.