博客 - JS/Ajax/AS

补习:跨平台的javascript事件

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);

解决方法:

function addEventHandler(oTarget, sEventType, fnHandler){
    
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] 或者 直接传入参数

解决方法:

function getEvent(){
    
if(window.event){
        
return window.event;
    
}else{
        
return getEvent.caller.arguments[0];
    
}
}

注:针对火狐的方法请参考 JavaScript 获取事件对象的一个注意点

获取事件属性:

相同处:

  1. 获取事件类型(名称):oEvent.type
  2. 获取按键代码(keydown/keyup事件):oEvent.keyCode
  3. 检测是否按下了Shift、Alt、Ctrl键:oEvent.shiftKey、oEvent.altKey、oEvent.ctrlKey
  4. 获取客户端鼠标事件坐标:oEvent.clientX、oEvent.clientY
  5. 获取鼠标距屏幕边沿坐标:oEvent.screenX、oEvent.screenY

不同处:

  1. 获取目标(事件源):

    IE:oEvent.srcElement

    火狐:oEvent.target

  2. 获取字符代码:

    IE:oEvent.keyCode

    火狐:oEvent.charCode

  3. 阻止事件发生:

    IE:oEvent.returnValue = false

    火狐:oEvent.preventDefault()

  4. 停止事件冒泡:

    IE:oEvent.cancelBubble = true

    火狐:oEvent.stopPropagation()

  5. 还有一些属性仅有火狐支持,比如eventPhase、isChar、pageX、pageY、

解决方法:

function formatEvent(oEvent){
    
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高级程序设计》,详细可翻阅该书籍。

标签:

1 条评论 发表在“补习:跨平台的javascript事件”上

  1. 网豪

    这个是怎么用的吖。可以举个例子出来吗?谢谢!!

    [回复]

写下您的看法

  • :em18:
  • :em12:
  • :em03:
  • :em08:
  • :em06:
  • :em05:
  • :em07:
  • :em15:
  • :em11:
  • :em16:
  • :em01:
  • :em17:
  • :em10:
  • :em13:
  • :em14:
  • :em02:
  • :em09:
  • :em04:

仅支持“a、abbr、strong、em、blockquote、code”几个简单的标签

使用腾讯微博登陆 使用新浪微博登陆