你让MSIE与W3C的注册事件真的统一了吗

说起页面元素的事件注册,一般我们都会写一个方法做一个包装,类似如下的方法(好像PPK的书中也是这样封装的)

function addEvent (eventType,listener,oTarget){
    if(oTarget.addEventListener){
        oTarget.addEventListener(eventType,listener,false);
    }
    else if(oTarget.attachEvent){
        oTarget.attachEvent('on'+eventType,listener);
    }
}

考虑到MSIE不支持捕获过程,我承认,没法达到真正意义上的统一,但这样做还会出现别的不谐调:

1、this问题:W3C的注册事件,在listener的方法体中,this是指向oTarget的,但MSIE中this还是指向window对象。

2、event对象:W3C的事件模型会在激发事件调用listener的时候传入一个event对象,而MSIE的不会传参,它的event对象是window对象的一个属性,所以我们没法统一listener的函数签名。

接下来,我们重新包装这个方法来修复这两个问题

function addEvent (eventType,listener,oTarget){
    if(window.addEventListener){
        oTarget.addEventListener(eventType,listener,false);
    }
    else if(window.attachEvent){
        oTarget.attachEvent( 'on'+type,  function(){listener.call(oTarget, window.event);} );
    }
}

通过call的方式,改变this的指向,并将window.event作为参数传给listener,并且可以统一listener的签名为listener(e),它是接受一个名为e的参数的。

其实这些问题高手们早已解决过了,这是John Resig的版本的部分代码

if(node.attachEvent) {
    node['e'+type+listener] = listener;//保证listener中的this是引用node
    node[type+listener] = function(){node['e'+type+listener]( window.event );}//保证event的传入
    node.attachEvent( 'on'+type, node[type+listener] );
}
posted @ 2011-03-15 17:16  他山之石_  阅读(395)  评论(0编辑  收藏  举报