There are two kinds of event bindings: Traditional event binding (inline model, script model), and modern event binding (DOM2 level model). Modern event bindings provide more powerful and convenient functionality on traditional bindings.
A problem with a traditional event binding
The inline model in traditional event binding is rarely used without discussion. Let's take a look at the scripting model, which assigns a function to an event handler. Traditional bindings such as:
Window.onload=function () {
var box=document.getelementbyid (' box ');
Box.onclick = function () {
alert (' Lee ');
};};
Problem One: An event-handler function triggers two events
If a page has two or more JS, and the first JS is the first program developed, the second JS is the second programmer developed. The first window.onload was covered, as
Window.onload=function () {
alert (' Lee ');
};
Window.onload=function () {
alert (' Mr.Lee ');
}
The results were just printed Mr.Lee
In fact, there are ways to solve this problem, look at the following two forms.
A:
alert (window.onload);//First unregistered window.onload, then null
window.onload=function () {
alert (' Lee ');
alert (window.onload);//If there is already a window.onload, the function functions
window.onload=function () {
alert (' Mr.Lee ') is printed;
}
B:
Alert (typeof window.onload);/No window.onolad at first, old version of Firefox display undefined, new version shows object,
window.onload=function () {
alert (' Lee ');
Alert (typeof window.onload);//If there is already window.onload, all browsers will display function
window.onload=function () {
alert (' Mr.Lee ');
}
So there's a solution.
Window.onload=function () {
alert (' Lee ');
};
if (typeof window.onload== ' function ') {
var saved=null;//saves the previous event object
saved=window.onload;
}
Saved is window.onload,saved () is equivalent to Window.onload (), but window.onload () cannot execute
//So Saved () is equivalent to window.onload= function () {}
window.onload=function () {
if (saved) {
saved ();//Execute Previous Event window.onload=function () {}
}
Alert (' Mr.Lee '); Execute this event
}
Issue two: Event switcher
Toggle a div with ID box so that the background red and blue are switched directly, and the frame is toggled once, such as:
Window.onload=function () {
var box=document.getelementbyid (' box ');
Box.classname= "Red";
Box.onclick=function () {
alert (' Lee ');///Only one
Blue.call (this) is executed;//execute a function through an anonymous function, then this is the window that represents. So you can pass it through call
.
}
function Blue () {
this.classname= "blue";
this.onclick=red;
}
function red () {
this.classname= "red";
This.onclick=blue;
}
Although the above code implements the switching function, the frame is only executed once.
Add Event function
//obj equivalent to window
//type equivalent to onload
//fn equivalent to function () {} function
addevent (OBJ,TYPE,FN) {
//Used to save the last event
var saved=null;
if (typeof obj[' on ' +type]== ' function ') {
saved=obj[' on ' +type];//save previous event
}
obj[' on ' +type]=function () {
if (saved) {
saved ();
}
Fn.call (this);
}
addevent (window, ' Load ', function () {
var Box=document.getelementbyid ("box");
addevent (box, ' click ', function () {//purpose achieved, executed each time, not covered
//alert (' SS ');
//});
addevent (box, ' click ', blue);
};
function red () {
this.classname= "red";
addevent (box, ' click ', blue);
}
function Blue () {
this.classname= "blue";
addevent (box, ' click ', red);
}
When constantly switching, the browser suddenly jammed, and the error: too much recursion, too many recursion
//Because accumulated too many saved events
//solutions, is used up the event, immediately removed
The error in the annotation appears in the preceding code, and the solution is as follows:
//Add Event function//obj equivalent to window//type equivalent to onload//FN is equivalent to the function () {} function addevent (Obj,type,
fn) {//used to save the last event Var Saved=null; if (typeof obj[' on ' +type]== ' function ') {saved=obj[' on ' +type];//Save last event} obj[' on ' +type]=function () {if (saved) {sav
Ed ();
} fn.call (this); }///When switching constantly, the browser suddenly jammed and gave an error: too much recursion, too many recursion//because there are too many saved events//solutions that are used up, remove//Remove event functions immediately.
Event (Obj,type) {if (obj[' on ' +type]) {obj[' on ' +type]=null;
} addevent (window, ' Load ', function () {var Box=document.getelementbyid ("box");
addevent (box, ' click ', function () {//purpose achieved, executed each time, not covered//alert (' SS ');
//});
addevent (box, ' click ', blue);
});
function red () {this.classname= "red";
Removeevent (This, ' click ');
addevent (box, ' click ', blue);
function Blue () {this.classname= "blue";
Removeevent (This, ' click ');
addevent (box, ' click ', red); }
Binary event handler function
AddEventListener () and RemoveEventListener ()
The two-event processing function of the AddEventListener () and the RemoveEventListener ().
Two add events and deletion events from the Consortium
1. Cover problem, solve
Window.addeventlistener (' Load ', function () {
alert (' Lee ');
},false)
; Window.addeventlistener (' Load ', function () {
alert (' Mr.Lee ');
},false)
; Window.addeventlistener (' Load ', function () {
alert (' Mrs.lee ');
},false);
2. The same function shielding problem, solve
Window.addeventlistener (' Load ', init,false);
Window.addeventlistener (' Load ', init,false);
Window.addeventlistener (' Load ', init,false);
function init () {
alert (' Lee ');
}
3. Can pass this, solve
Example 1:
Window.addeventlistener (' Load ', function () {
var box=document.getelementbyid (' box ');
Box.addeventlistener (' click ', Function () {
alert (this);
},false);
},false);
Example 2:
Window.addeventlistener (' Load ', function () {
var box=document.getelementbyid (' box ');
Box.addeventlistener (' click ', Blue,false);
},false)
; function red () {
this.classname= "red";
This.removeeventlistener (' click ', Red,false);
This.addeventlistener (' click ', Blue,false);
}
function Blue () {
this.classname= "blue";
This.removeeventlistener (' click ', Blue,false);
This.addeventlistener (' click ', Red,false);
}
4. Add an additional method that will not be overwritten, or can only be executed once, to resolve
Window.addeventlistener (' Load ', function () {
var box=document.getelementbyid (' box ');
Box.addeventlistener (' click ', Function () {
alert (' Lee ');
},false);
Box.addeventlistener (' click ', Blue,false);
},false);
To sum up: The Web is a relatively perfect solution to these problems, very useful, but IE8 and previous browsers do not support, but the adoption of their own events, of course, IE9 has fully supported the two event processing functions of the consortium.
The consortium can set bubbles and capture modes.
Browsers that support the Web-consortium standard Use the AddEventListener (event,fn,usecapture) method when adding events, Kizhong the 3rd parameter usecapture is a Boolean value that is used to set the event to execute when the event is captured. Or when the event bubbles. Browsers that are not compatible with the Web (IE) use the attachevent () method, this method has no relevant settings, but the IE event model is performed by default when the event bubbles, that is, when the usecapture equals false, So it's safer to set the Usecapture to false when handling events, and also to implement browser-compatible effects.
Event Capture Phase: an event is searched down from the top level of the tag until the event target (target) is captured.
Event bubbling phase: The event starts at the event target and bubbles up until the top level of the page tag.
The propagation of events can be blocked:
In the consortium, use the Stoppropagation () method
Set cancelbubble = True under IE;
Three. IE Event handling function
Attachevent () and DetachEvent ()
IE implements two methods similar to the DOM: Attachevent () and DetachEvent (). The two methods accept the same arguments: the event name and the function.
In the use of these two sets of functions, the difference is first said: 1. IE does not support capturing, only bubbles are supported, 2. IE Add event cannot mask duplicate function; 3. This in IE refers to window rather than to a DOM object. 4. In traditional events, IE is not acceptable to the event object, but the use of attchevent but can, but some differences.
1. Covering issues, resolved, but different, the result is Mrs.lee,mr.lee, and finally Lee
Window.attachevent (' onload ', function () {
alert (' Lee ');
});
Window.attachevent (' onload ', function () {
alert (' Mr.Lee ');
});
Window.attachevent (' onload ', function () {
alert (' Mrs.lee ');
});
2. The same function shielding problem, not resolved.
Window.attachevent (' onload ', init);
Window.attachevent (' onload ', init);
function init () {
alert (' Lee ');
}
3. Can pass this, cannot, this refers to window. You need to use the call method.
Window.attachevent (' onload ', function () {
var box=document.getelementbyid (' box ');
Box.attachevent (' onclick ', function () {
//alert (this===box);
alert (This===window); True
});
The next way is through the window.event.srcElement. The code is as follows:
Window.attachevent (' onload ', function () {
var box=document.getelementbyid (' box ');
Box.attachevent (' onclick ', blue);
};
function red () {
var that=window.event.srcelement;
That.classname= "Red";
That.detachevent (' onclick ', red);
That.attachevent (' onclick ', blue);
}
function Blue () {
var that=window.event.srcelement;
That.classname= "Blue";
That.detachevent (' onclick ', blue);
That.attachevent (' onclick ', red);
}
4. Add an additional method that will not be overwritten, or can only be executed once, resolved.
On traditional bindings, IE is not able to accept event objects by reference, as in the case of the World Service, but using attachevent () is OK.
Window.attachevent (' onload ', function () {
var box=document.getelementbyid (' box ');
Box.onclick=function (EVT) {//traditional method ie cannot get evt
alert (evt) via parameters;//undefined
}
box.attachevent (' OnClick ', function (evt) {
alert (evt);//object
alert (evt.type);//click
alert ( Evt.srcElement.tagName);//div
alert (window.event.srcElement.tagName);//div
});
Cross-browser compatibility
Adding events across browsers
function Addevent (OBJ,TYPE,FN) {
if (obj.addeventlistener) {
obj.addeventlistener (type,fn,false);
} else if (obj.attachevent) {
obj.attachevent (' on ' +type,fn);
}
}
Cross-browser removal events
function Removeevent (OBJ,TYPE,FN) {
if (obj.removeeventlistener) {
Obj.removeeventlistener (type,fn,false );
} else if (obj.detachevent) {
obj.detachevent (' on ' +type,fn);
}
}
Get target objects across browsers
function Gettarget (evt) {
if (evt.target) {return
evt.target;
} else if (window.event.srcElement) {return
window.event.srcElement
}}
Call Mode:
addevent (window, ' Load ', function () {
var box=document.getelementbyid (' box ');
addevent (box, ' click ', blue);
};
function Red (evt) {
var that=gettarget (evt);
That.classname= "Red";
Removeevent (That, ' click ', red);
Addevent (That, ' click ', blue);
}
function Blue (evt) {
var that=gettarget (evt);
That.classname= "Blue";
Removeevent (That, ' click ', blue);
Addevent (That, ' click ', red);
}
Four. Other additions to the event object
Relatedtarget Events
A Relatedtarget event in the consortium.
For example:
addevent (window, ' Load ', function () {
var box=document.getelementbyid (' box ');
addevent (box, ' mouseover ', function (evt) {
alert (evt.relatedtarget);//Get the DOM object recently moved into Box
});
addevent (box, ' mouseout ', function (evt) {
alert (evt.relatedtarget);//move from box to the nearest DOM object
});
IE provides two sets of attributes Fromelement and toelement, respectively, for moving and moving out, corresponding to MouseOver and mouseout respectively.
addevent (window, ' Load ', function () {
var box=document.getelementbyid (' box ');
addevent (box, ' mouseover ', function () {
alert (window.event.fromElement.tagName);//Get the DOM object recently moved into Box
});
addevent (box, ' mouseout ', function () {
alert (window.event.toElement.tagName);//Move the nearest DOM object} from Box
);
Ps:fromelement and toelement have no meaning if they correspond to the opposite mouse events respectively.
All that's left to do is cross-browser-compatible operations:
function Gettarget (evt) {
var e=evt | | window.event;
if (e.srcelment) {//ie
if (e.type== ' mouseover ') {return
e.fromelement.tagname;
} else if (e.type= "Mouseout") {return
e.toelement.tagname
}}
else if (e.relatedtarget) {//w3c return
e.relatedtarget
}}
Mask Jump Action
There is an irregular way to cancel the default behavior of an event, or to return false.
Link.onclick=function () {
alert (' Lee ');
return false;
}
PS: Although return false, this functionality can be implemented, but there are vulnerabilities.
First: Must be written to the last, so that the winning code after the execution, it is possible to perform less than return false;
Second: return false to the top then the custom action is invalidated.
So the best way to do this is to block the default behavior at the front, and the following code can be executed.
Link.onclick=function (evt) {
evt.preventdefault;//w3c, blocking default behavior
alert (' Lee ');
}
Link.onclick=function (evt) {
window.event.returnvalue=false;//ie, blocking default behavior
alert (' Lee ');
}
Cross-browser compatibility:
function Predef (evt) {
var e=evt | | window.event;
if (e.preventdefault) {
e.preventdefault ();
} else{
e.returnvalue=false
}
}
Right-click menu ContextMenu
Compatible:
function Predef (evt) {
var e=evt | | window.event;
if (e.preventdefault) {
e.preventdefault ();
} else{
e.returnvalue=false
}
}
addevent (window, "Load", function () {
var body=document.getelementsbytagname (' body ') [0];
Addevent (Body, ' ContextMenu ', function (evt) {
predef (evt);
})
});
Ps:contextmenu events are common, which directly results in a more stable browser compatibility.
Pre-uninstall Event: Beforeunload
This event can help you to leave this page with the appropriate prompts, "leave" or "return" action.
addevent (window, ' beforeonload ', function () {
predef (evt);
});
Mouse wheel (mousewheel) and Dommousescroll
Used to get the distance of the scroll wheel on the mouse
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| | window.event;
if (E.wheeldelta) {return
e.wheeldelta;
} else if (e.detail) {//Firefox
return-evt.detail*30
}
}
PS: Through browser detection can be sure that Firefox only executes Dommousescroll.
domcontentloaded Events and ReadyStateChange events
domcontentloaded events and ReadyStateChange events, events on DOM loading.