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