首页 > 代码库 > ie7、ie8兼容addEventListener和removeEventListener,解决this指向和detachEvent解除绑定事件问题

ie7、ie8兼容addEventListener和removeEventListener,解决this指向和detachEvent解除绑定事件问题

现代浏览器监听事件使用addEventListener函数,解除绑定监听使用removeEventListener函数。但是ie7、ie8监听事件使用attachEvent函数,解除监听事件使用detachEvent函数。

简单的兼容函数:

1 if(document.addEventListener){2     element.addEventListener(type, fun, useCapture);3 }else{4     element.addEventListener("on" + type, fun);5 }

 

addEventListener绑定的监听事件,事件内this指向element。但是attachEvent绑定的监听事件,事件内this指向window,使用call或者apply可以解决该问题,修改this指向element,event作为参数传递。

 1 var addListener = (function(){ 2     if(document.addEventListener){ 3         return function(element, type, fun, useCapture){ 4             element.addEventListener(type, fun, useCapture ? useCapture : false); 5         };     6     }else{ 7         return function(element, type, fun){ 8             element.attachEvent("on" + type, function(event){ 9                 fun.call(element, event);10             });11         };12     }13 })();

 

但是这样也有个问题,就是detachEvent无法解除监听,因为传递的事件已经改变了。通过function.prototype将修改后的函数和已经绑定该事件的dom储存起来,可以使detachEvent时能获取到解除监听的函数,addEventListener自己会避免多次绑定一个事件,attachEvent需要自己判断是否绑定多次事件。

 1 /** 2  * addEventlistener兼容函数 3  * ie9以上正常使用addEventlistener函数 4  * ie7、ie8用传递的function的function.prototype储存经过处理的事件 5  * function.prototype["_" + type]:记录处理后的信息 6  * function.prototype["_" + type]._function <function>:经过处理的事件 7  * function.prototype["_" + type]._element  <array>   :已经绑定的dom 8  */ 9 10 /*** addEventlistener ***/11 var addListener = (function(){12     if(document.addEventListener){13         /* ie9以上正常使用addEventListener */14         return function(element, type, fun, useCapture){15             element.addEventListener(type, fun, useCapture ? useCapture : false);16         };17     }else{18         /* ie7、ie8使用attachEvent */19         return function(element, type, fun){20             if(!fun.prototype["_" + type]){21                 /* 该事件第一次绑定 */22                 fun.prototype["_" + type] = {23                     _function: function(event){24                         fun.call(element, event);25                     },26                     _element: [element]27                 };28                 element.attachEvent("on" + type, fun.prototype["_" + type]._function);29             }else{30                 /* 该事件被绑定过 */31                 var s = true;32                 // 判断当前的element是否已经绑定过该事件33                 for(var i in fun.prototype["_" + type]._element){34                     if(fun.prototype["_" + type]._element[i] === element){35                         s = false;36                         break;37                     }38                 }39                 // 当前的element没有绑定过该事件40                 if(s === true){41                     element.attachEvent("on" + type, fun.prototype["_" + type]._function);42                     fun.prototype["_" + type]._element.push(element);43                 }44             }45         };46     }47 })();48 /*** removeEventlistener ***/49 var removeListener = (function(){50     if(document.addEventListener){51         /* ie9以上正常使用removeEventListener */52         return function(element, type, fun){53             element.removeEventListener(type, fun);54         };55     }else{56         /* ie7、ie8使用detachEvent */57         return function(element, type, fun){58             element.detachEvent("on" + type, fun.prototype["_" + type]._function);59             if(fun.prototype["_" + type]._element.length === 1){60                 // 该事件只有一个element监听,删除function.prototype["_" + type]61                 delete fun.prototype["_" + type];62             }else{63                 // 该事件只有多个element监听,从function.prototype["_" + type]._element数组中删除该element64                 for(var i in fun.prototype["_" + type]._element){65                     if(fun.prototype["_" + type]._element[i] === element){66                         fun.prototype["_" + type]._element.splice(i, 1);67                         break;68                     }69                 }70             }71         };72     }73 })();

ie7、ie8兼容addEventListener和removeEventListener,解决this指向和detachEvent解除绑定事件问题