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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ie7ie8兼容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数组中删除该element
64                 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 })();

以上是关于ie7ie8兼容addEventListener和removeEventListener,解决this指向和detachEvent解除绑定事件问题的主要内容,如果未能解决你的问题,请参考以下文章

js绑定事件方法:addEventListener的兼容问题

addEventListener和attachEvent的区别(转载)

封装addEventListener,removeEventListener指定元素添加事件及兼容问题js

封装addEventListener,removeEventListener指定元素添加事件及兼容问题js

js绑定事件方法:addEventListener与attachEvent的不同浏览器的兼容性写法

js绑定事件和解绑事件