补习:跨平台的javascript事件
2010-03-20 下午 - JS/Ajax/AS - event - 兼容性
javascript的事件模型有三种:netscape、IE、W3C/Safari。
事件流又分冒泡型事件和捕获型事件。主要的浏览器代表是netscape、IE7及以下版本。
DOM事件流:同时支持冒泡型事件和捕获型事件。火狐、Safari、IE8等支持DOM事件流的浏览器。
以下内容仅以IE和火狐作为代表进行对比及处理。
添加、移除事件:
IE
oTarget.attachEvent("on" + sEventType, fnHandler);
oTarget.detachEvent("on" + sEventType, fnHandler);
火狐:
oTarget.addEventListener(sEventType, fnHandler, false);
oTarget.removeEventListener(sEventType, fnHandler, false);
解决方法:
if(oTarget.addEventListener){
oTarget.addEventListener(sEventType,fnHandler,false);
}else if(oTarget.attachEvent){
oTarget.attachEvent("on" + sEventType,fnHandler);
}else{
oTarget["on" + sEventType]=fnHandler;
}
}
function removeEventHandler(oTarget, sEventType, fnHandler){
if(oTarget.removeEventListener){
oTarget.removeEventListener(sEventType,fnHandler,false);
}else if(oTarget.detachEvent){
oTarget.detachEvent("on" + sEventType,fnHandler);
}else{
oTarget["on" + sEventType]=null;
}
}
获取事件对象:
IE
IE中,事件对象是window对象的一个属性event。
window.event
火狐:
DOM标准中,event对象必须作为唯一参数传给事件处理函数。
arguments[0] 或者 直接传入参数
解决方法:
if(window.event){
return window.event;
}else{
return getEvent.caller.arguments[0];
}
}
注:针对火狐的方法请参考 JavaScript 获取事件对象的一个注意点
获取事件属性:
相同处:
- 获取事件类型(名称):
oEvent.type - 获取按键代码(keydown/keyup事件):
oEvent.keyCode - 检测是否按下了Shift、Alt、Ctrl键:
oEvent.shiftKey、oEvent.altKey、oEvent.ctrlKey - 获取客户端鼠标事件坐标:
oEvent.clientX、oEvent.clientY - 获取鼠标距屏幕边沿坐标:
oEvent.screenX、oEvent.screenY
不同处:
-
获取目标(事件源):
IE:
oEvent.srcElement火狐:
oEvent.target -
获取字符代码:
IE:
oEvent.keyCode火狐:
oEvent.charCode -
阻止事件发生:
IE:
oEvent.returnValue = false火狐:
oEvent.preventDefault() -
停止事件冒泡:
IE:
oEvent.cancelBubble = true火狐:
oEvent.stopPropagation() - 还有一些属性仅有火狐支持,比如eventPhase、isChar、pageX、pageY、
解决方法:
if (isIE && isWin) {
oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
oEvent.eventPhase = 2;
oEvent.isChar = (oEvent.charCode > 0);
oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
oEvent.pageY = oEvent.clientY + document.body.scrollTop;
oEvent.preventDefault = function () {
this.returnValue = false;
};
if (oEvent.type == "mouseout") {
oEvent.relatedTarget = oEvent.toElement;
} else if (oEvent.type == "mouseover") {
oEvent.relatedTarget = oEvent.fromElement;
}
oEvent.stopPropagation = function () {
this.cancelBubble = true;
};
oEvent.target = oEvent.srcElement;
oEvent.time = (new Date).getTime();
}
return oEvent;
}
最后综合起来,EventUtil对象封装起来,就很好的解决了事件的跨平台兼容了。下载:eventutil.js。
此文中涉及到的浏览器检测功能,超出了本文的范围,略过!detect.js 提供代码方便下载测试。
本文参考自《javascript高级程序设计》,详细可翻阅该书籍。