Recently in-depth practice js, encountered some problems, such as I need to create a dynamic DOM element binding event, then the ordinary event binding is not, so through the Internet to check the data to understand the event delegate, so want to summarize the JS event binding and event Delegation.
Event Bindings
Most immediate event Bindings: HTML event handlers
The following example code, explicitly declared by the node property, explicitly binds the button to the click event directly in the html, triggering the Myclickfunc method when the button has user click Behavior.
/* HTML */
<button id= "btn" onclick= "myclickfunc ()" >
ClickMe
</button>
/* JS */
Event handlers
var Myclickfunc = function (evt) {
Todo..
};
Removing event handlers
Myclickfunc = function () {};
obviously, This kind of binding method is very unfriendly, HTML code and JS code are seriously coupled, such as when you want to modify a function name, it is necessary to modify two times,
DOM Level 0 Event handlers
Dynamic binding of events via DOM is a traditional way of assigning a function to an event handler. This way is also more application of the way, relatively simple. Look at the following example:
/* HTML */
<button id= "btn" >ClickMe</button>
/* JS */
Event handlers
var Myclickfunc = function (evt) {
Todo...
};
Assign a value directly to the OnClick method of the DOM node, notice that a function is received here
document.getElementById (' btn '). onclick = myclickfunc;
Removing event handlers
document.getElementById (' btn '). onclick = null;
DOM Level 2 event handlers
Events are bound by event snooping, and the DOM2 level event defines two methods for handling the actions of the specified and deleted event Handlers.
Event: Events Name
Function: Event functions
Boolean:false | true, true for event capture, false for event bubbling (default);
Ele.addeventlistener (event,function[,boolean]); Add handle
Ele.removeeventlistener (event,function[,boolean]); Remove handle
Look at an example:
/* HTML */
<button id= "btn" >ClickMe</button>
/* JS */
Dynamic binding via Dom Operations:
Get Btnhello Node
var obtn = document.getElementById (' btn ');
Add the first click event Listener Handler
Obtn.addeventlistener (' Click ', function (evt) {
TODO sth 1 ...
});
Add a second Click event Listener Handler
Obtn.addeventlistener (' Click ', function (evt) {
TODO sth 2 ...
});
Ps: in this form, you can bind any number of click Listeners to the BTN button; Note that the order of execution is related to the order of Addition.
Removing event handlers
Obtn.removeeventlistener (' Click ', function (evt) {.});
IE Event handlers
DOM Level 2 event handlers do not work in ie, IE has its own event handler Method: attachevent () and DetachEvent (). The usage of these two methods is the same as AddEventListener (), but only two parameters are received, one is the event name and the other is the function of the event Handler. Why not use the third parameter for a reason? Because IE8 and earlier browser versions only support event Bubbling. Look at an example:
/* HTML */
<button id= "btn" >ClickMe</button>
/* JS */
var obtn = document.getElementById (' btn ');
Event handler function
function Evtfn () {
Console.log (this);
}
Add handle
Obtn.attachevent (' onclick ', evtfn);
Remove handle
Obtn.detachevent (' onclick ', evtfn);
Easy Cross-browser Solution
If we both support the event processing method of IE and support DOM Level 2 event, then we should encapsulate a Cross-browser event handler and use AddEventListener if I support DOM Level 2 event, or use Attachevent. Examples are as Follows:
Cross-browser Event handlers
var eventutil = {
Add handle
Addhandler:function (element, type, Handler) {
If (element.addeventlistener) {
Element.addeventlistener (type, handler, false);
}else if (element.attachevent) {
Element.attachevent (' on ' + type, handler);
}else{
element[' on ' + type] = handler;
}
},
Delete Handle
Removehandler:function (element, type, Handler) {
If (element.removeeventlistener) {
Element.removeeventlistener (type, handler, false);
}else if (element.detachevent) {
Element.detachevent (' on ' + type, handler);
}else{
element[' on ' + type] = null;
}
}
};
var obtn = document.getElementById (' btn ');
function Evtfn () {
Alert (' Hello World ');
}
Eventutil.addhandler (obtn, ' click ', evtfn);
Eventutil.removehandler (obtn, ' click ', evtfn);
Event bubbling and Event capture
Before you know the event delegate, you should understand the following event bubbling and event Capture.
Early Web development, browser vendors have a hard time answering a philosophical question: which element are you really interested in when you click on an area of the page? This problem brings about the definition of Interaction. Clicking within the bounds of an element appears somewhat Vague. After all, a click on one element also occurs within the bounds of another element. For example, Click a button. You actually clicked on the button area, the area of the body element, and the area of the HTML Element.
With this problem, the two main browsers Netscape and IE have different solutions. Netscape defines a processing method called Event capture, which occurs first in the top-level object (document) of the DOM tree and then propagates toward the deepest element. In the legend, the event capture occurs first on the document, then the HTML element, the body element, and finally the button Element.
IE is handled in the opposite way. They define a method called event Bubbling. Event bubbling considers the deepest element of an event's promotion to receive the event First. Then it's the parent element, which, in turn, knows that the document object eventually receives the Event. Although document has no independent visual representation relative to the HTML element, he is still the parent element of the HTML element and the event can bubble to the document Element. So in the legend, oh Oh the button element receives the event first, then the body, and the HTML finally the Document. Such as:
Event bubbling
To put it simply, event bubbling is the event trigger that propagates upward from the target DOM element until the document root node, in general, is propagated as Follows:
targetdom→parentnode→ ... →body→document→window
If you want an event trigger to respond to the entire DOM tree, you need to use the mechanism of event bubbling. Look at the following example:
/* HTML */
<button id= "btn" >ClickMe</button>
/* JS */
Add click Listener to the button
document.getElementById (' btn '). addeventlistener (' Click ', function (evt) {
Alert (' Button Clicked ');
},false);
Add Click Listener to Body
Document.body.addEventListener (' Click ', function (evt) {
Alert (' Body Clicked ');
},false);
In this case, after clicking the button "clickme", its own Click event will be triggered, and the event will continue to propagate upward, all ancestor nodes will get the event trigger command, and immediately trigger their own click event, so the above code, will be a continuous popup two Alert.
In some cases, we want events to be triggered independently, so we have to stop bubbling, using the Stoppropagation () method of the Event.
<button id= "btn" >ClickMe</button>
/* JS */
Add click Listener to the button
document.getElementById (' btn '). addeventlistener (' Click ', function (evt) {
Alert (' Button Clicked ');
Evt.stoppropagation (); Block event bubbling
},false);
Add Click Listener to Body
Document.body.addEventListener (' Click ', function (evt) {
Alert (' Body Clicked ');
},false);
At this point, when the button is clicked, only the Click event of the button itself will be triggered, and the Click event of the button will not propagate upward, and the body node will not receive the event Command.
It is important to note that:
Not all events can bubble, such as: blur, focus, load, unload can not
Different browsers, the way to prevent bubbling is not the same, in the standard, through event.stoppropagation () completed, in IE is through its own event.cancelbubble=true to Complete.
Event delegate
The event delegate may seem difficult to understand, but give a life example. For example, 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. As an example,
HTML structure:
<ul id= "ul-item" >
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
If we want to click on the Li tag and pop up the content, we need to bind the event for each Li Tag.
(function () {
var oulitem = document.getElementById (' ul-item ');
var oLi = Oulitem.getelementsbytagname (' li ');
For (var i=0, L = oli.length; I < l; i++) {
Oli[i].addeventlistener (' Click ', show);
};
Function Show (e) {
E = e | | window.event;
Alert (e.target.innerhtml);
};
})();
Although this can achieve the functionality we want, but if the LI element in this UL is frequently added or deleted, we need to bind the event to it each time we add li. This adds complexity and creates a large memory overhead.
An easier approach is to use event delegates to judge and get the event source Li by examining the Event's target object (target) when the event is fetched to the parent node of the higher layer.
(function () {
var oulitem = document.getElementById (' ul-item ');
Oulitem.addeventlistener (' Click ', show);
Function Show (e) {
E = e | | window.event;
var src = e.target;
If (src && src.nodeName.toLowerCase () = = = ' Li ') {
Alert (src.innerhtml);
}
}
})();
Here we add a click event for the parent node ul, and when you click on the Sub-node Li tag, The Click event Bubbles to the parent Node. After the parent node captures the event, it is judged by the e.target.nodename to determine if it is the node that we need to process, and through E.target gets the clicked Li Node. So that you can get the corresponding information and do the Processing.
Advantages:
With the introduction above, you should be able to appreciate several advantages of using event Delegation for Web Applications:
There are fewer functions to manage. You do not need to add a listener function for each element. For a child element similar to the same parent node, the event can be handled by delegating a listener function to the parent Element.
You can easily add and modify elements dynamically, without modifying the event bindings because of changes to the Elements.
There is less association between JavaScript and Dom nodes, which reduces the probability of a memory leak due to circular references.
Resources
Http://www.diguage.com/archives/71.html
Http://owenchen.net/?p=15
Turn from: 1190000006667581
Allin
Understanding event binding and event delegation in JavaScript