你的位置:首页 > Java教程

[Java教程]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 })();