- 在浏览器中,dom监听事件使用addEventListener(removeEventListener);
在ie7、ie8中,监听事件使用attachEvent(detachEvent)。
if(document.addEventListener){
element.addEventListener(type, fun, useCapture);
}else{
element.addEventListener("on" + type, fun);
}
- addEventListener绑定的监听事件,事件内this指向element。但是attachEvent绑定的监听事件,事件内this指向window,使用call或者apply可以解决该问题,修改this指向element,event作为参数传递。
var addListener = (function(){
if(document.addEventListener){
return function(element, type, fun, useCapture){
element.addEventListener(type, fun, useCapture ? useCapture : false);
};
}else{
return function(element, type, fun){
element.attachEvent("on" + type, function(event){
fun.call(element, event);
});
};
}
})();
但是这样也有个问题,就是detachEvent无法解除监听,因为传递的事件已经改变了。
- 通过function.prototype将修改后的函数和已经绑定该事件的dom储存起来,可以使detachEvent时能获取到解除监听的函数,并且避免dom多次绑定重复事件。
/**
* addEventlistener兼容函数
* ie9以上正常使用addEventlistener函数
* ie7、ie8用传递的function的function.prototype._bindFun储存经过处理的事件和对应的节点
* function.prototype._bindFun[index].type:绑定的事件类型
* function.prototype._bindFun[index].element:绑定的节点
* function.prototype._bindFun[index].Function:处理的事件
*/
/*** addEventlistener ***/
const addListener = (()=>{
if(document.addEventListener){
/* ie9以上正常使用addEventListener */
return function(element, type, fun, useCapture){
element.addEventListener(type, fun, useCapture ? useCapture : false);
};
}else{
/* ie7、ie8使用attachEvent */
return function(element, type, fun){
if(!fun.prototype._bindFun){
fun.prototype._bindFun = [];
}
// 判断当前的element是否已经绑定过该事件
let s = true;
for(const i in fun.prototype._bindFun){
if(fun.prototype._bindFun[i].type === type && fun.prototype._bindFun[i].element === element){
s = false;
break;
}
}
// 没有绑定事件
if(s === true){
const f = {
type: type,
element: element,
Function: function(event){
fun.call(element, event);
}
};
fun.prototype._bindFun.push(f);
element.attachEvent(`on${type}`, f.Function);
}
};
}
})();
/*** removeEventlistener ***/
const removeListener = (()=>{
if(document.addEventListener){
/* ie9以上正常使用removeEventListener */
return function(element, type, fun){
element.removeEventListener(type, fun);
};
}else{
/* ie7、ie8使用detachEvent */
return function(element, type, fun){
for(const i in fun.prototype._bindFun){
if(fun.prototype._bindFun[i].type === type && fun.prototype._bindFun[i].element === element){
element.detachEvent(`on${type}`, fun.prototype._bindFun[i].Function);
fun.prototype._bindFun.splice(i, 1);
break;
}
}
};
}
})();