本文主要谈及问题:
- 关于编写跨浏览器的事件处理函数和事件对象
关于编写跨浏览器的事件处理函数和事件对象
-
为什么要编写跨浏览器的事件处理函数和事件对象
近几年来,个人对WINDOWS越来越没爱。至于为什么无爱,我想原因有二:
- 转投MAC阵营,觉得MAC比起WINDOWS对用户太友好了
- 成为了一个前端工程师
讲讲第二点。网上一直流传着一个段子:IE都有勇气让你把它设为默认浏览器,为什么你还连表白的勇气都没有。每每看到这个段子,心都有点痛,我想不仅是我,每个前端工程师都会有这样的感觉。微软在IE9之前,完全是think different ,make 更加 different。做出来的东西完全跟标准不一致。FE们为了兼容它没少花心思。就拿事件模型来说,基本上最常用的模型有两种:一种是DOM L2 EVENT MODEL.另外一种不用说,相信大家都知道,就是IE EVENT.所以我们就被逼着编写跨浏览器的事件处理函数和事件对象。是不是觉得IE很作死,可是没办法啊,人家还占那么多份额,我们只能乖乖地兼容它。
-
怎么编写跨浏览器的事件处理函数和事件对象
-
事件处理函数
-
DOM 事件处理函数(这里只谈及DOM2)
DOM2级事件定义了两种方法:- addEventListener(type,handler,useCapture); --添加事件处理函数
- removeEventListener(type,handler,useCapture); -- 删除事件处理函数
这两个方法都有三个参数:type为事件的类型,handler为事件处理程序的函数,userCapture(可选参数)为事件流类型,冒泡为false,捕获为true,默认为false。
-
IE 事件处理函数
IE 事件定义了两种方法:- 添加事件处理函数 :attachEvent("on"+type,handler);
- 删除事件处理函数 :detachEvent("on"+type,handler);
这两个方法都有两个参数:第一个参数"on"+type是事件类型(如果在addEventListener的type为click,则此处应该为onclick),第二个参数handler为事件处理程序的函数。注意:IE8之前的浏览器只支持事件冒泡,不支持事件捕获。
-
区别:
-
一个元素添加多个事件处理函数的执行顺序:如果为一个元素添加多个事件处理函数,addEVentListener会按照添加的顺序执行代码。而attachEvent会按照添加顺序的相反顺序,如下:
var btn = document.getElementById('btn'); btn.addEventListener("click",function(){ alert("1"); }); btn.addEventListener("click",function(){ alert("2"); }); //以上代码先输出1,在输出2 var btn = document.getElementById('btn'); btn.attachEvent("onclick"function(){ alert("1"); }) btn.attachEvent("onclick"function(){ alert("2"); }) //以上代码先输出2,再输出1
-
事件处理程序的函数中的this:addEventListener的handler中的this指的是添加该事件处理函数的元素,而attachEvent的handler中的this指的是window对象。如下:
var bt = document.getElementById("bt"); bt.addEventListener("click",function(){ console.log(this === bt) }) //为true,this指添加事件处理函数的元素 var bt = document.getElementById("bt"); bt.attachEvent("onclick",function(){ console.log(this === window) }) //为true,this指window对象
-
-
跨浏览器事件处理函数 :
综合上述的事件处理函数,我们可以写出跨浏览器的事件处理函数,我们可以把它包含在一个对象里。如下:var eventForAllBrowsers = { addHandler :function(elem,type,handler){ if(elem.addEventListener){ elem.addEventListener(type,handler,false); } else if(elem.attachEvent){ elem.attachEvent("on"+type,handler); } else{ elem["on"+type] = handler; //加上对DOM 0 的支持 } }, removeHandler:function(elem,type,handler){ if(elem.removeEventListener){ elem.removeEventListener(type,handler,false) } else if(elem.detachEvent){ elem.detachEvent("on"+type,handler); } else { elem["on"+type] = null; } } }
-
-
事件对象
- DOM 事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中。在函数内可以访问event对象的属性与方法。如下:
var bt = document.getElementById('bt');
bt.addEventListener("click",function(event){
alert(event.type)
})
event对象中包含的常用的属性和方法:- preventDefault() --- 取消事件的默认行为。
- stopPropagation() --- 取消事件的进一步冒泡。
- type --- 被触发的事件的类型。
- target --- 事件的目标。
- IE 事件对象
与兼容DOM的浏览器不同,要访问IE的event对象分两种情况:-
使用DOM 0 方法添加事件处理程序:在程序的函数内,用window.event去访问event对象。如下:
var bt = document.getElementById('bt'); bt.onclick = function(){ var event = window.event; alert(event.type) }
-
使用IE 事件处理函数:将event对象传入事件处理程序的函数内。如下:
var bt = document.getElementById('bt'); bt.attachEvent("onclick",function(event){ alert(event.type) })
-
-
event对象中包含的常用的属性和方法:
- cacelBubble --- 默认值为false,将其设置为true就可以取消事件冒泡。
- returnValue --- 默认值为true,将其设置为false则可以取消事件的默认行为。
- srcElement --- 事件的目标。
- type --- 被触发事件的类型。
- 跨浏览器的事件对象
通过检查兼容DOM的浏览器的event对象的方法和属性是否存在的方法去处理跨浏览器兼容性问题。把通用的事件对象的相关函数添加到eventForAllBrowsers上,代码大致如下:
var eventForAllBrowsers = {
//省略上述的代码
getEvent :function(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){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
}
网友评论