javascript event binding learning points
- 2021-01-25 07:04:00
- OfStack
Event binding is divided into two types: one is the traditional event binding (inline model, script model), the other is the modern event binding (DOM2-level model). Modern event bindings provide more powerful and convenient functions over traditional bindings.
Problems with traditional event binding
The inline model in traditional event binding is not discussed and is rarely used. Let's start with the script 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 1:1 an event handler fires two events
If a page has two or more js, and the first js is developed by the first program, and the second js is developed by the second programmer. The first window.onload is overwritten, as in
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
The result is only Mr.lee
There's actually a way to solve this problem. Let's look at the two forms.
a:
alert(window.onload);//1 No registration at first window.onload, It is null
window.onload=function(){
alert('Lee');
};
alert(window.onload);// If you already have window.onload, It's a function function
window.onload=function(){
alert('Mr.lee');
}
b:
alert(typeof window.onload);//1 Start no window.onolad, Old versions of Firefox undefined, The new show object,
window.onload=function(){
alert('Lee');
};
alert(typeof window.onload);// If you already have window.onload, It will be displayed in all browsers 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;// Save on 1 Event objects
saved=window.onload;
}
//saved is window.onload,saved() The equivalent of window.onload(), but window.onload() unexecutable
// so saved() The equivalent of window.onload=function(){}
window.onload=function(){
if(saved){
saved();// To perform the 1 An event window.onload=function(){}
}
alert('Mr.lee'); // Execute this event
}
Problem 2: Event switcher
Switch 1 div with box as id, and switch the background red and blue directly, and pop-up once before switching, such as:
window.onload=function(){
var box=document.getElementById('box');
box.className="red";
box.onclick=function(){
alert('Lee'); // Only performed 1 time
blue.call(this);// Executes something through an anonymous function 1 Delta function, so the inner delta this Is the representative of window, So you can go through call pass
};
}
function blue(){
this.className="blue";
this.onclick=red;
}
function red(){
this.className="red";
this.onclick=blue;
}
The above code implements the toggle function, but the popup box only executes once.
// Adding Event Functions
//obj The equivalent of window
//type The equivalent of onload
//fn The equivalent of function(){}
function addEvent(obj,type,fn){
// For preservation 1 An event
var saved=null;
if(typeof obj['on'+type]=='function'){
saved=obj['on'+type];// Save on 1 An event
}
obj['on'+type]=function(){
if(saved){
saved();
}
fn.call(this);
}
}
addEvent(window,'load',function(){
var box=document.getElementById("box");
//addEvent(box,'click',function(){ // The goal is achieved. Every time it is executed, it is not overwritten
// 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 switching, the browser suddenly freezes and returns an error: too much recursion, Too much recursion
// Because there are too many saved events
// The solution is to remove the used events as soon as possible
There is an error in the comment according to the above code. The solution is as follows:
// Adding Event Functions
//obj The equivalent of window
//type The equivalent of onload
//fn The equivalent of function(){}
function addEvent(obj,type,fn){
// For preservation 1 An event
var saved=null;
if(typeof obj['on'+type]=='function'){
saved=obj['on'+type];// Save on 1 An event
}
obj['on'+type]=function(){
if(saved){
saved();
}
fn.call(this);
}
}
// When switching, the browser suddenly freezes and returns an error: too much recursion, Too much recursion
// Because there are too many saved events
// The solution is to remove the used events as soon as possible
// Remove event function
function removeEvent(obj,type){
if(obj['on'+type]){
obj['on'+type]=null;
}
}
addEvent(window,'load',function(){
var box=document.getElementById("box");
//addEvent(box,'click',function(){ // The goal is achieved. Every time it is executed, it is not overwritten
// 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);
}
2 W3C event handler
With removeEventListener addEventListener () ()
Two W3C event handlers, addEventListener() and removeEventListener().
//W3C has two add events and delete events
1. Coverage problem, solved
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, solved
window.addEventListener('load',init,false);
window.addEventListener('load',init,false);
window.addEventListener('load',init,false);
function init(){
alert('Lee');
}
3. Can we pass this
Example 1:
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
0
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 extra method, will it be overridden, or can only be executed once, resolved
window.addEventListener('load',function(){
var box=document.getElementById('box');
box.addEventListener('click',function(){
alert('Lee');
},false);
box.addEventListener('click',blue,false);
},false);
To summarize: W3C is a relatively perfect solution to these problems, very easy to use, but IE8 and previous browsers do not support, but use their own events, of course, IE9 has fully supported W3C these two event handlers.
W3C can set the bubble and capture mode.
Browsers that support W3C use the addEventListener(event,fn,useCapture) method when adding events. The third parameter, useCapture, is an Boolean value, which sets whether the event is executed when the event is caught or when the event is bubbling. And incompatible W3C browser (IE) using attachEvent () method, this method is not related to setup, but the default IE event models is performed when event bubbling, namely when useCapture equals false execution, so when processing events set useCapture to false is safer, and the effect of implementation browser compatibility.
Event capture phase: Events are searched from the topmost 1-level tag down until the event target (target) is captured.
Event bubbling phase: Events start at the event target (target) and bubble up to the top 1-level tag on the page.
The propagation of the event can be prevented:
In W3c, the stopPropagation() method is used
Set cancelBubble = true under IE;
3.IE event handler
attachEvent () and detachEvent ()
IE implements two methods similar to those in DOM: attachEvent() and detachEvent(). Both methods take the same arguments: the event name and the function.
1.IE does not support capture, only bubbling; 2.IE does not support capture, only bubbling. 2.IE add events cannot mask duplicate functions; 3. this in IE refers to window and not to DOM objects. 4. In traditional events, IE does not accept event objects, but using attchEvent does, with some differences.
1. Coverage problem solved, but with a difference, the result is Mrs.Lee, Mr.Lee, and finally Lee
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
3
2. The same function masking problem, not resolved.
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
4
3. Can you pass this? No, this means window. The call method is required.
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
5
The next option is window.event.srcElement. The code is as follows:
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
6
4. Add an extra method, will it be overridden, or can only be executed once, resolved.
In traditional bindings, IE cannot accept event objects by passing arguments as W3C does, but using attachEvent() can.
window.attachEvent('onload',function(){
var box=document.getElementById('box');
box.onclick=function(evt){ // The traditional method IE Cannot be obtained from a parameter evt
alert(evt);//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
Add 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);
}
}
Removes events across browsers
window.onload=function(){
alert('Lee');
};
window.onload=function(){
alert('Mr.lee');
}
9
Get the target object 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);
}
4. Additional additions to event objects
relatedTarget event
relatedTarget event in w3c.
Such as:
addEvent(window,'load',function(){
var box=document.getElementById('box');
addEvent(box,'mouseover',function(evt){
alert(evt.relatedTarget); // Get moving box The nearest one DOM object
});
addEvent(box,'mouseout',function(evt){
alert(evt.relatedTarget); // from box Move out the nearest one DOM object
});
});
IE provides two sets of migration in and out attributes fromElement and toElement, 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 moving box The nearest one DOM object
});
addEvent(box,'mouseout',function(){
alert(window.event.toElement.tagName); // from box Move out the nearest one DOM object
});
});
PS:fromElement and toElement have no meaning if they correspond to opposite mouse events.
All that's left to do is work across browsers:
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;
}
}
Shield jump operations
A non-standard way to cancel the default behavior of an event is to return false.
link.onclick=function(){
alert('Lee');
return false;
}
PS: Although return, false; You can do this, but there are bugs.
1. The code must be written to the end, so that the winning code may not execute return false after execution.
return: false writes to the very top, then any subsequent custom operations will fail.
So the best thing to do is to block the default behavior up front and let the code execute later.
link.onclick=function(evt){
evt.preventDefault;//w3c, Preventing default behavior
alert('Lee');
}
link.onclick=function(evt){
window.event.returnValue=false;//IE, Preventing default behavior
alert('Lee');
}
So 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 with:
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: The contextmenu event is very common, which directly results in stable browser compatibility.
Pre-uninstall event: beforeunload
This event helps to indicate when leaving the page, "leave" or "return" actions.
addEvent(window,'beforeonload',function(){
preDef(evt);
});
Mouse Wheel (mousewheel) and DOMMouseScroll
Used to get the distance of the mouse wheel up and down
addEvent(document,'mousewheel',function(evt){ // The 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: Browser checks confirm that Firefox only executes DOMMouseScroll.
DOMContentLoaded event and readystatechange event
DOMContentLoaded event and readystatechange event, events about the loading aspect of DOM.