Event binding is divided into two types: one is traditional event binding (inline model, script model), and the other is modern event binding (DOM2 level model). Modern event binding provides more powerful and convenient functions on traditional binding.
1. The issue of traditional event binding
The inline model in traditional event binding is not discussed and is rarely used. Let’s first look at the script model. The script model assigns a function to an event processing function. Traditional bindings such as:
=function(){ var box=('box'); = function(){ alert('Lee'); }; };
Question 1: An event handler triggers two events
If a page has two or more js, and the first js is developed by the first program, the second js is developed by the second programmer. The first one is covered,
=function(){ alert('Lee'); }; =function(){ alert(''); }
It turned out to be printed
In fact, there is a way to solve this problem, look at the following two forms.
a:
alert();//No registration at the beginning, then it's null =function(){ alert('Lee'); }; alert();//If there is already a function, the function is printed =function(){ alert(''); }
b:
alert(typeof );//Not at the beginning, the old version of Firefox shows undefined, the new version shows object, =function(){ alert('Lee'); }; alert(typeof );//If there is already a function, all browsers will display a function =function(){ alert(''); }
So there is a solution.
=function(){ alert('Lee'); }; if(typeof =='function'){ var saved=null;//Save the previous event object saved=; } //saved means that saved() is equivalent to(), but() cannot be executed//So saved() is equivalent to = function(){} =function(){ if(saved){ saved();//Execute the previous event =function(){} } alert(''); //Execute this event}
Question 2: Event Switcher
Switch a div with id as box, let the background red and blue directly switch directly, and switch the previous pop-up box once, such as:
=function(){ var box=('box'); ="red"; =function(){ alert('Lee'); //Only executed once (this);//Execute a certain function through an anonymous function, then this inside represents the window, so it can be passed through the call }; } function blue(){ ="blue"; =red; } function red(){ ="red"; =blue; }
Although the above code implements the switching function, the pop-up box is only executed once.
//Add event function//obj is equivalent to window//type is equivalent to onload//fn is equivalent to function(){}function addEvent(obj,type,fn){ // Used to save the previous event var saved=null; if(typeof obj['on'+type]=='function'){ saved=obj['on'+type];//Save the previous event } obj['on'+type]=function(){ if(saved){ saved(); } (this); } } addEvent(window,'load',function(){ var box=("box"); //addEvent(box,'click',function(){ //The purpose is achieved, it is executed every time, and it is not overwritten // alert('ss'); //}); addEvent(box,'click',blue); }); function red(){ ="red"; addEvent(box,'click',blue); } function blue(){ ="blue"; addEvent(box,'click',red); } //When switching constantly, the browser suddenly gets stuck and an error is reported: too much recursion, too much recursion//Because too many saved events have been accumulated//The solution is to remove the event immediately after running out
According to the above code, an error in the comment appeared. The solution is as follows:
//Add event function//obj is equivalent to window//type is equivalent to onload//fn is equivalent to function(){}function addEvent(obj,type,fn){ // Used to save the previous event var saved=null; if(typeof obj['on'+type]=='function'){ saved=obj['on'+type];//Save the previous event } obj['on'+type]=function(){ if(saved){ saved(); } (this); } } //When switching constantly, the browser suddenly gets stuck and an error is reported: too much recursion, too much recursion//Because too many saved events have been accumulated//The solution is to remove the event immediately after running out //Remove event functionfunction removeEvent(obj,type){ if(obj['on'+type]){ obj['on'+type]=null; } } addEvent(window,'load',function(){ var box=("box"); //addEvent(box,'click',function(){ //The purpose is achieved, it is executed every time, and it is not overwritten // alert('ss'); //}); addEvent(box,'click',blue); }); function red(){ ="red"; removeEvent(this,'click'); addEvent(box,'click',blue); } function blue(){ ="blue"; removeEvent(this,'click'); addEvent(box,'click',red); }
2. W3C event handling function
addEventListener() and removeEventListener()
There are two W3C event handling functions, addEventListener() and removeEventListener().
//W3C comes with two addition events and deletion events
1. Coverage the problem and solve it
('load',function(){ alert('Lee'); },false); ('load',function(){ alert(''); },false); ('load',function(){ alert(''); },false);
2. The problem of blocking the same function will be solved
('load',init,false); ('load',init,false); ('load',init,false); function init(){ alert('Lee'); }
3. Can this be passed?
Example 1:
('load',function(){ var box=('box'); ('click',function(){ alert(this); },false); },false);
Example 2:
('load',function(){ var box=('box'); ('click',blue,false); },false); function red(){ ="red"; ('click',red,false); ('click',blue,false); } function blue(){ ="blue"; ('click',blue,false); ('click',red,false); }
4. Add an extra method, will it be overwritten, or can only be executed once, and solve it
('load',function(){ var box=('box'); ('click',function(){ alert('Lee'); },false); ('click',blue,false); },false);
To sum up: W3C solves these problems perfectly and is very useful, but IE8 and previous browsers do not support it, but use its own events. Of course, IE9 has fully supported these two event handling functions of W3C.
W3C can set up bubble and capture methods.
Browsers that support W3C standard use the addEventListener(event,fn,useCapture) method when adding events. The third parameter in the base is a Boolean value, which is used to set whether the event is executed during event capture or when the event is bubbled. However, browsers that are not compatible with W3C use the attachEvent() method. There is no relevant setting for this method. However, the IE event model is executed by default when the event is bubbled, that is, when useCapture is equal to false, so it is safe to set useCapture to false when processing events, and also achieves the effect of compatible browsers.
Event capture stage: The event starts from the top-level tag and looks down until the event target is captured.
Event Bubble Phase: The event starts from the event target and bubbles up until the top level tag of the page.
The spread of events can be prevented:
In W3c, use stopPropagation() method
Set cancelBubble = true under IE;
IE event handling function
attachEvent() and detachEvent()
IE implements two methods similar to those in DOM: attachEvent() and detachEvent(). These two methods accept the same parameters: event name and function.
When using these two sets of functions, let me first talk about the difference: it does not support capture, it only supports bubbles; adding events cannot block duplicate functions; this in it points to window rather than DOM objects. 4. In traditional events, IE cannot accept event objects, but using attachEvent can do so, but there are some differences.
1. The problem of coverage was solved, but there was a difference, and the result was, in the end, Lee
('onload',function(){ alert('Lee'); }); ('onload',function(){ alert(''); }); ('onload',function(){ alert(''); });
2. The problem of blocking the same function has not been solved.
('onload',init); ('onload',init); function init(){ alert('Lee'); }
3. Whether this can be passed, no, this refers to window. Call method is required.
('onload',function(){ var box=('box'); ('onclick',function(){ //alert(this===box); alert(this===window); //true }); });
The following is another way to pass. The code is as follows:
('onload',function(){ var box=('box'); ('onclick',blue); }); function red(){ var that=; ="red"; ('onclick',red); ('onclick',blue); } function blue(){ var that=; ="blue"; ('onclick',blue); ('onclick',red); }
4. Add an extra method, will it be overwritten, or can only be executed once, and resolve.
In traditional binding, IE cannot accept event objects by passing parameters like W3C, but using attachEvent() is OK.
('onload',function(){ var box=('box'); =function(evt){ //The traditional method IE cannot obtain evt through parameters alert(evt);//undefined } ('onclick',function(evt){ alert(evt);//object alert();//click alert();//DIV alert();//DIV }); });
Cross-browser compatibility
Add events across browsers
function addEvent(obj,type,fn){ if(){ (type,fn,false); }else if(){ ('on'+type,fn); } }
Cross-browser removal event
function removeEvent(obj,type,fn){ if(){ (type,fn,false); }else if(){ ('on'+type,fn); } }
Get target object across browsers
function getTarget(evt){ if(){ return ; }else if(){ return ; } }
Call method:
addEvent(window,'load',function(){ var box=('box'); addEvent(box,'click',blue); }); function red(evt){ var that=getTarget(evt); ="red"; removeEvent(that,'click',red); addEvent(that,'click',blue); } function blue(evt){ var that=getTarget(evt); ="blue"; removeEvent(that,'click',blue); addEvent(that,'click',red); }
IV. Other supplements to event objects
relatedTarget event
A relatedTarget event in w3c.
For example:
addEvent(window,'load',function(){ var box=('box'); addEvent(box,'mouseover',function(evt){ alert(); //Get the nearest DOM object moved into the box }); addEvent(box,'mouseout',function(evt){ alert(); //Move the nearest DOM object from the box }); });
IE provides two sets of attributes fromElement and toElement for moving in and out, corresponding to mouseover and mouseout respectively.
addEvent(window,'load',function(){ var box=('box'); addEvent(box,'mouseover',function(){ alert(); //Get the nearest DOM object moved into the box }); addEvent(box,'mouseout',function(){ alert(); //Move the nearest DOM object from the box }); });
PS: fromElement and toElement correspond to opposite mouse events respectively, there is no meaning.
All that remains to be cross-browser compatible:
function getTarget(evt){ var e=evt || ; if(){ //IE if(=='mouseover'){ return ; }else if(="mouseout"){ return ; } }else if(){ //w3c return ; } }
Blocking jump operation
There is an irregular approach to canceling the default behavior of events, which is to return false.
=function(){ alert('Lee'); return false; }
PS: Although return false; this function can be implemented, there are loopholes.
First: It must be written to the end, so that the winning code may not be executed after it is executed, return false may not be executed;
Second: return false When writing to the beginning, the custom operation afterwards will be invalid.
So the best way is to block the default behavior at the beginning, and the subsequent code can be executed.
=function(evt){ ;//w3c, block default behavior alert('Lee'); } =function(evt){ =false;//IE, block default behavior alert('Lee'); }
Then cross-browser compatibility:
function preDef(evt){ var e=evt || ; if(){ (); }else{ =false; } }
Right-click menu contextmenu
compatible:
function preDef(evt){ var e=evt || ; if(){ (); }else{ =false; } } addEvent(window,"load",function(){ var body=('body')[0]; addEvent(body,'contextmenu',function(evt){ preDef(evt); }) });
PS: The contextmenu event is very commonly used, which directly leads to relatively stable browser compatibility.
Before uninstall event: beforeunload
This event can help give corresponding prompts when leaving this page, "Leave" or "Return" operations.
addEvent(window,'beforeonload',function(){ preDef(evt); });
Mousewheel and DOMMouseScroll
Used to get the distance between the mouse up and down scroll wheels
addEvent(document,'mousewheel',function(evt){ //Non-Firefox alert(getWD(evt)); }); addEvent(document,'DOMMouseScroll',function(evt){ //Firefox alert(getWD(evt)); }); function getWD(evt){ var e=evt|| ; if(){ return ; }else if(){ //Firefox return -*30; } }
PS: Through browser detection, it can be determined that Firefox only executes DOMMouseScroll.
DOMContentLoaded event and readystatechange event
DOMContentLoaded event and readystatechange event, events related to DOM loading.