JS event Monitoring Mechanism (event capture) Summary __js

Source: Internet
Author: User
Tags event listener unique id

In the front-end development process, we often encounter problems with adding events to page elements, add the event of the JS method is also a lot of directly added to the page structure, there is a use of some JS event monitoring method, due to the different browser event bubbling event monitoring mechanism, le browser only event bubbling, There is no mechanism for event sniffing, and compatibility issues with event sniffing are the biggest challenges:

1. Write the method of the event directly on the page structure


function Eventfun () { 
//console.log (this); 
} 
<input type= "button" onclick= "Eventfun ()" value= "button"/>
//Here is a question about this scope, Eventfun again here is a global function, the object is [ Object Window],this points to Window.

To resolve the problem with this scope, you can use a method that adds an event variable to a global function to pass the This object as a parameter to the function inside the page structure

<input type= "button" onclick= "eventfun2 (This)" value= "button2"/> 
function eventfun2 (Eve) {// This is where the event object is passed as a parameter to the global method 
eve.name= "Alex"; 
Window.name= "Robin"; 
Console.log (this);//[object Window] 
Console.log (Eve);//[Object Htmlinputelement] 
console.log (this.name) ;//Robin 
Console.log (eve.name);//Alexvar 
Self=eve; 
Console.log (this.name);//robin 
Console.log (self.name);//alex 
alert (window.name) 
; alert (self.name); 
}

2. Using a method to assign a value to an event property is a way to bind to an event, but the limitation of this approach is that only one method can be bound for the event, and if multiple bindings are followed, then one method will prevail.

Htmlelementobject.onclick = Fucntion () {//using this method of assigning a value to an event property, this pointer points to a Window object rather than being an event object, so this method is a reference

JS Code 
fun1 (); 
Fun2 (); 
Fun3 (); 
Console.log (this);//window.object 
} 
function dosomething () { 
//js code 
} 
Htmlelementobject.onclick = dosomething;//uses this form of assigning values to event object properties, this pointer points to the event execution Object 
Console.log (this); Htmlelementobject

3. Event propagation- bubbling and capturing
The DOM event standard defines two event flows, which are significantly different and may have considerable impact on your application. The two event streams are captured and bubbling, respectively. Like many web technologies, Netscape and Microsoft implemented them differently before they became standard. Netscape chose to implement the capture event stream, while Microsoft implemented the bubbling event stream . Fortunately, the consortium decides to use both methods, and most new browsers follow these two types of event flow.
By default, events use a bubbling event stream and do not use a capture event stream . However, in Firefox and Safari, you can explicitly specify the use of a capture event stream by passing in the Usecapture argument when registering the event, and setting this argument to true.


Bubbling event Stream
When an event is triggered by a DOM element, the for example, when a user clicks on a client name node, the event bubbles through the entire DOM node hierarchy with each parent node that the node inherits from, until it encounters a node that is attached to the processor of that event type, at which point the event is the onclick event. The bubbling of events can be terminated at any time during the bubbling process, and the stoppropagation() method on the event object can be invoked in Internet Explorer by setting the object 's The Cancelbubble property is true. If you do not stop the propagation of the event, the event continues to bubble through the DOM until the document root is reached. that is, from the clicked element to the ancestor element of this element up to the root element, from bottom to top.


Capturing an event stream
The processing of the event begins at the root of the DOM hierarchy, rather than from the target element that triggers the event, which is passed in sequence from all ancestor elements of the target element. In this process, events are captured by elements that derive from the document root to the event target element, and if the event listener sets the Usecapture property to True when it is registered, then they can be assigned to any element of the period to handle the event; The event is then passed to the next element on the path of the derived element, until the target element. When an event reaches the target element, it then bubbles through the DOM node. That is, the root element to the clicked element, from top to bottom.


Modern event binding methods
There are many drawbacks to using traditional event bindings, such as the inability to register multiple event handlers on the same event for an object. Browsers and the web also do not take this into account, so in modern browsers they have their own way of binding events.
The Consortium DOM
The method provided by obj.addeventlistener(evtype,fn,usecapture)--w3c to add an event-handling function. Obj is the object to add the event, Evtype is the event type, without the on prefix, FN is the event handler, and if Usecapture is true, the event handler function is executed during the capture phase, otherwise in the bubbling phase
The method provided by obj.removeeventlistener(evtype,fn,usecapture)--w3c to delete event handlers


Microsoft IE method
The method provided by obj.attachevent(EVTYPE,FN)--ie to add an event-handling function. Obj is the object to add the event, Evtype is the event type, with the on prefix, FN is the event handler, IE does not support event capture
obj.detachevent(EVTYPE,FN,)--ie a method for deleting an event handler, Evtype containing an on prefix

Ways to integrate both

function Addevent (obj,evtype,fn,usecapture) { 
if (obj.addeventlistener) { 
Obj.addeventlistener (EVTYPE,FN, usecapture); 
} else { 
obj.attachevent ("on" +EVTYPE,FN);//ie does not support event capture 
} else { 
obj["on" +evtype]=fn;//in fact this does not exist 
} 
} 
function Delevent (obj,evtype,fn,usecapture) { 
if (obj.removeeventlistener) { 
Obj.removeeventlistener ( evtype,fn,usecapture); 
} else { 
obj.detachevent ("on" +EVTYPE,FN); 
} else { 
obj[' on ' +evtype]=null; 
} 
}

The problem with IE's attach approach is that, inside the event handler function when using attachevent, this points to window instead of obj. Of course, there is a solution to this.

But the Attachevent method of IE has another problem, the same function can be registered to the same object on the same event many times, the solution: Abandon IE attachevent method. The Attachevent method under IE does not support capturing, and is not much different from traditional event registration (except for the ability to bind multiple event handlers), and the Attachevent method of IE has a memory leak problem.


Addevent,delevent Modern Edition

<body> <div id= "Outele" style= "padding:10px; border:1px solid #b2b2b2; Background: #efefef; " > <input type= "button" onclick= "Eventfun ()" id= "button" value= "button"/><br/> <input type= "button" O nclick= "Eventfun2" (this); "Id=" Button2 "value=" Button2 "/><br"/> <input type= "button" id= "Button3" value= " Button3 "/><br/> <input type=" button "id=" Button4 "value=" Button4 "/><br/>" <table id= "Htmlelet" Able "width=" 100% "border=" 0 "style=" border:1px solid #b2b2b2; Background: #fff; " > <tr id= "1111" ><td>111111111111111111111111111111</td></tr> <tr id= "22222" >< td>222222222222222222222222222222</td></tr> <tr id= "33333" ><td> 333333333333333333333333333333</td></tr> <tr id= "4444" ><td> 444444444444444444444444444444</td></tr> <tr id= "55555" ><td> 555555555555555555555555555555</td></tr> </table> </div> 
<script language= "javascript" type= "Text/javascript" > Function Eventfun () {//1. Write the JS method directly on the page structure Console.log (this 
//Here is a question about this scope, Eventfun again here is a global function where the object is Window,this pointing to Window alert (this); 
Function Eventfun2 (Eve) {//Here the event object is passed as a parameter to the global method Eve.name= "Alex";/window.name= "Robin"; 
Console.log (this);//[object Window] Console.log (Eve);//[Object Htmlinputelement] Console.log (this.name); Robin 
Console.log (Eve.name)/Alex var Self=eve; 
Console.log (this.name);//robin Console.log (self.name);//alex alert (window.name); 
alert (self.name); function Eventfun3 () {//1. Write the JS method directly on the page structure Console.log (this);//Here is a question about this scope, Eventfun here is a global function, object is window, 
This point is window Console.log (this.id); 
alert (this); 
alert (this.id); 
var outeleobj = eventutil.$ ("Outele"); 
Removeevent (Outeleobj, "click", Eventfun3); 
}/* var eventutil = {}; 
eventutil.$ = function (ID) {return document.getElementById (ID); 
} eventutil.openmes = Eventfun3; Eventutil.addeventhandle = function (EventtArget,eventtype,eventhandle) {//define object element for event listener, event type, event function if (eventtarget.attachevent) {eventtarget.attachevent ("on" + 
Eventtype,eventhandle); 
}else if (eventtarget.addeventlistener) {Eventtarget.addeventlistener (eventtype,eventhandle,false)}else{ 
Eventtarget["on" + eventtype] = null; 
} 
 
}; Eventutil.deleeventhandle = function (eventtarget,eventtype,eventhandle) {//define object element for event listener, event type, event function if ( 
eventtarget.detachevent) {alert ("on" +eventtype); 
Alert ("on" +eventhandle); 
Eventtarget.detachevent ("on" +eventtype,eventhandle); 
}else if (eventtarget.removeeventlistener) {Eventtarget.removeeventlistener (eventtype,eventhandle,false)}else{ 
Eventtarget["on" + eventtype] = null; 
};*/var eventutil={$:function (ID) {return document.getElementById (ID); 
}, But4fun:function () {console.log (this); 
This.addeventhandle (); 
}, Eventfun3:function () {console.log (this); 
alert (this); 
Delevent (obj,evtype,fn,usecapture); }/*** the Listener function addevent for DOM events using addeventlistener,attachevent (obj, evtype,fn,usecapture) {if (Obj.addeventlistener) {Obj.addeventlistener (evtype,fn,usecapture); 
}else if (obj.attachevent) {obj.attachevent ("on" +evtype,function () {fn.call (obj); 
}); }else {obj["on" +evtype]=fn;//in fact this does not exist} function delevent (obj,evtype,fn,usecapture) {if (Obj.removeeventlisten 
ER) {obj.removeeventlistener (evtype,fn,usecapture); 
else if (obj.detachevent) {obj.detachevent ("on" +EVTYPE,FN); 
else {obj["on" +evtype]=null; } function Addevent (obj,evtype,fn,usecapture) {if (Obj.addeventlistener) {/////priority for the event registration scheme Obj.addeventlistene R (Evtype,fn,!! 
Usecapture); else {//when AddEventListener is not supported (IE), because IE also does not support capture, it is better to use the traditional event binding if (!fn.__eventid) {Fn.__eventid = addevent.__ 
eventhandlescounter++;} 
Assigns a unique ID if (!obj.__eventhandles) {obj.__eventhandles={} to each event-handling function; The __eventhandles property is used to hold references to all event-handling functions//by Event type if (!obj.__eventhandles[evtype]) {//When the first time an event is registered Obj.__eventhandles[evtype 
]={}; if (obj["on" +evtype]) {//has previously registered the event handler function in a traditional manner (obj.__eventhandles[evtype][0]=obj["on" +evtype]). __eventid=0;//added to reserved 0 bits//and added an ID to the original event handler obj["on" +evtype]= 
Addevent.execeventhandles; 
When the event occurs, Execeventhandles traverses the table Obj.__eventhandles[evtype] and executes the function} addevent.__eventhandlescounter=1;//counter, which is reserved for 0 bits 
Addevent.execeventhandles = function (evt) {//Traverse all event handler functions and perform if (!this.__eventhandles) {return true;} EVT = EVT | | 
window.event; 
var FNS = This.__eventhandles[evt.type]; 
for (var i, FNS) {fns[i].call (this); 
} 
}; 
/* Function Delevent (obj,evtype,fn,usecapture) {if (Obj.removeeventlistener) {//Remove event handler by using the method of the consortium first Obj.removeeventlistener (EVTYPE,FN,!! 
Usecapture); 
else {if (obj.__eventhandles) {var fns = Obj.__eventhandles[evtype]; 
if (FNS) {delete Fns[fn.__eventid];} }} function Fixevent (evt) {//fixevent function is not executed separately, it must have an event object argument, and it is executed only if the event occurs. 
The best approach is to integrate it into the execeventhandles of the Addevent function if (!evt.target) {evt.target = evt.srcelement; 
Evt.preventdefault = Fixevent.preventdefault; Evt.stoppropagation = Fixevent. stoppropagation; 
if (Evt.type = = "MouseOver") {evt.relatedtarget = evt.fromelement; 
else if (Evt.type = = "Mouseout") {evt.relatedtarget = evt.toelement; 
} Evt.charcode = (evt.type== "KeyPress")? evt.keycode:0; 
Evt.eventphase = 2;//ie works only in the bubbling phase Evt.timestamp = (new Date ()). GetTime ();//Only set it to the current time} return evt; 
Fixevent.preventdefault =function () {this.returnvalue = false;//This here points to an event object instead of Fixevent}; 
Fixevent.stoppropagation =function () {this.cancelbubble = true; };*///console.log (eventutil.$ ("Button3"))//Returns the object property Eventutil ("//eventutil.$") of the Button3 function. onclick= EVENTFUN;//2. Implements the Listener//eventutil.$ ("Button3") of the event using a method that assigns values to the Object event property. onclick= eventfun2;//The latter//eventutil.$ ("Button3") when adding more than one method for an event property. onclick= eventfun;//event capture is from an object-by-layer parent to the Window object var eventutil =function () {function GetByID (ID) {return document.gete 
Lementbyid (ID); 
}; Written by Dean Edwards, on//with input from Tino Zijdel, Matthias Miller, Diego perini//Http://dean.edwards. Name/weblog/2005/10/add-event/function addevent (element, type, handler) {if (Element.addeventlistener) {Element.addeventlistener (type 
, handler, false); 
else {//Assign each event handler a unique ID if (!handler.$ $guid) handler.$ $guid = addevent.guid++; 
Create a hash table of event types for the element if (!element.events) element.events = {}; 
Create a hash table of event handlers for each element/event pair var handlers = Element.events[type]; 
if (!handlers) {handlers = Element.events[type] = {}; 
Store the existing event handler (if there is one) if (element[' on ' + type]) {handlers[0] = element[' on ' + type]; 
}//Store the event handler in the hash table handlers[handler.$ $guid] = handler; 
Assign a global event handler to does all the work element[' on ' + type] = Handleevent; 
} 
}; 
 
A counter used to create unique IDs addevent.guid = 1; function removeevent (element, type, handler) {if (Element.removeeventlistener) {Element.removeeventlistener (type),handler, false); else {//delete the event handler from the hash table if (element.events && Element.events[type]) {Delete E 
lement.events[type][handler.$ $guid]; 
 
} 
} 
}; 
function Handleevent (event) {var returnvalue = true; Grab the Event object (IE uses a global event object) event = Event | | 
Fixevent ((this.ownerdocument | | this.document | | this). parentwindow | | window). event); 
Get a reference to the hash table of event handlers var handlers = This.events[event.type]; 
Execute each event handler to (Var i in handlers) {this.$ $handleEvent = handlers[i]; 
if (this.$ $handleEvent (event) = = False) {returnvalue = false; 
} return returnvalue; 
 
}; 
function Fixevent (event) {//Add standard event methods Event.preventdefault = Fixevent.preventdefault; 
Event.stoppropagation = fixevent.stoppropagation; 
return event; 
}; 
Fixevent.preventdefault = function () {this.returnvalue = false; 
}; Fixevent.stoppropagation = function () {this.caNcelbubble = true; 
}; 
 
function Tableaddevent () {}; 
 
return{add:addevent, Remove:removeevent, $:getbyid}} (); 
var outeleobj = eventutil.$ ("Outele"); 
Addevent.apply (Eventutil,[outeleobj, "click", Eventfun3]); 
Eventutil.add (Outeleobj, "click", Eventfun3); 
var inputobj = eventutil.$ ("Button4"); 
var Tableele = eventutil.$ ("htmleletable"); 
var Tabtrele = Tableele.getelementsbytagname ("tr"); 
Eventutil.add (Tableele, "click", Eventfun3); 
For (i=0 i<tabtrele.length; i++) {eventutil.add (tabtrele[i), "click", Eventfun3); } eventutil.remove (Tableele, "click", Eventfun3)//events take the Delete method Eventutil.add (Tableele, "click", Eventfun3);//Event bubbling Add method// 
Eventutil.add (Inputobj, "click", Eventfun3); 
Eventutil.remove (Outeleobj, "click", Eventfun3); 
Console.log (addevent); 
Addevent (Inputobj, "click", Eventfun3,true); 
Delevent (Outeleobj, "click", Eventfun3,false);  </script> </body>



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.