一、HTML事件处理
1、优点:
- 在HTML中指定事件处理会创建一个封装着元素属性值的函数。这个函数有一个局部变量event,也就是事件对象,通过event变量,可以直接访问事件对象。
- 可以使用with扩展作用域,目的是想让时间处理程序无需引用就能访问其他表单字段。
2、缺点:
- 存在时差问题。
- 事件处理程序的作用域链在不同的浏览器中有不同的结果。
- HTML和JavaScript代码紧密耦合,要更换事件处理程序,就需要改动两个地方:HTML代码和JavaScript代码。
通过分析,在复杂程序中尽量用JavaScript指定事件处理程序。
二、DOM0级事件处理程序
1、通过JavaScript指定事件处理程序的传统方式是将一个函数赋值给一个事件处理程序属性。传统方式优点:一是简单;而是具有跨浏览器的优势。要使用JavaScript指定事件处理程序,首先必须取得一个要操作的对象引用。
2、每个元素都有自己的事件处理程序属性,属性通常全部小写。将属性值设置为一个函数,就可以指定事件处理程序。
DOM0级事件处理程序被认为是元素的方法,是在元素的作用域中运行,函数中的this引用当前元素,this可以访问元素的所有属性和方法。
3、删除DOM0事件处理程序:btn.onclick = null;
三、DOM2级事件处理程序
1、定义了两个方法,用于处理制定和删除事件处理程序的操作:addEventListener()和removeEventListener(),所有DOM节点都支持。
都接受三个函数参数:要处理的事件名、座位事件处理程序的函数和一个布尔值。如果布尔值为true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
2、使用DOM2级方法可以添加多个事件处理程序,多个事件的执行顺序按照添加他们的顺序触发。
3、addEventListener()只能用removeEventListener()方法移除,这也意味着通过addEventListener()添加的匿名函数无法移除。
4、多数情况下,都是将事件处理程序添加到事件的冒泡阶段,这样可以最大限度的兼容各种浏览器(意味着第三个布尔值尽量填false).
IE9、Firefox、Safari、Chrome和Opera支持DOM2级事件处理程序。
四、IE事件处理程序
1、attachEvent()和detachEvent()接收相同的两个参数:事件处理程序名称和事件处理函数。事件名在DOM2中是“click”,在IE中是“onclick”。
2、在IE中使用attachEvent()与使用DOM0方法区别在于事件处理的作用域不同。在DOM0级方法中,事件处理程序会在所属的元素的作用域中运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。
3、在添加多个方法时,执行顺序是按照定义相反的顺序执行。
4、移除事件处理程序:detachEvent(),只要能够将对相同函数的引用传给detachEvent(),就可以移除相应的事件处理程序。
var btn = document.getElementById("myBtn");
var handler = function(){
alert("clicked");
}
btn.attachEvent("onclick",handler);
btn.detachEvent("onclick",handler);
只有IE和Opera支持IE事件处理程序。
五、跨浏览器的事件处理程序
来一个改写自Zakas大神的跨浏览器事件处理对象
var EventUtil={
addHandler:function(element,type,handler){ //添加事件
if(element.addEventListener){
element.addEventListener(type,handler,false); //使用DOM2级方法添加事件
}else if(element.attachEvent){ //使用IE方法添加事件
element.attachEvent("on"+type,handler);
}else{
element["on"+type]=handler; //使用DOM0级方法添加事件
}
},
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;
}
},
getEvent:function(event){ //使用这个方法跨浏览器取得event对象
return event?event:window.event;
},
getTarget:function(event){ //返回事件的实际目标
return event.target||event.srcElement;
},
preventDefault:function(event){ //阻止事件的默认行为
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
stopPropagation:function(event){ //立即停止事件在DOM中的传播
//避免触发注册在document.body上面的事件处理程序
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
},
getRelatedTarget:function(event){ //获取mouseover和mouseout相关元素
if(event.relatedTarget){
return event.relatedTarget;
}else if(event.toElement){ //兼容IE8-
return event.toElement;
}else if(event.formElement){
return event.formElement;
}else{
return null;
}
},
getButton:function(event){ //获取mousedown或mouseup按下或释放的按钮是鼠标中的哪一个
if(document.implementation.hasFeature("MouseEvents","2.0")){
return event.button;
}else{
switch(event.button){ //将IE模型下的button属性映射为DOM模型下的button属性
case 0:
case 1:
case 3:
case 5:
case 7:
return 0; //按下的是鼠标主按钮(一般是左键)
case 2:
case 6:
return 2; //按下的是中间的鼠标按钮
case 4:
return 1; //鼠标次按钮(一般是右键)
}
}
},
getWheelDelta:function(event){ //获取表示鼠标滚轮滚动方向的数值
if(event.wheelDelta){
return event.wheelDelta;
}else{
return -event.detail*40;
}
},
getCharCode:function(event){ //以跨浏览器取得相同的字符编码,需在keypress事件中使用
if(typeof event.charCode=="number"){
return event.charCode;
}else{
return event.keyCode;
}
}
};