- 在瀏覽器中,dom監(jiān)聽事件使用addEventListener(removeEventListener);
在ie7、ie8中,監(jiān)聽事件使用attachEvent(detachEvent)。
if(document.addEventListener){
element.addEventListener(type, fun, useCapture);
}else{
element.addEventListener("on" + type, fun);
}
- addEventListener綁定的監(jiān)聽事件,事件內(nèi)this指向element。但是attachEvent綁定的監(jiān)聽事件,事件內(nèi)this指向window,使用call或者apply可以解決該問題,修改this指向element,event作為參數(shù)傳遞。
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無法解除監(jiān)聽,因為傳遞的事件已經(jīng)改變了。
- 通過function.prototype將修改后的函數(shù)和已經(jīng)綁定該事件的dom儲存起來,可以使detachEvent時能獲取到解除監(jiān)聽的函數(shù),并且避免dom多次綁定重復(fù)事件。
/**
* addEventlistener兼容函數(shù)
* ie9以上正常使用addEventlistener函數(shù)
* ie7、ie8用傳遞的function的function.prototype._bindFun儲存經(jīng)過處理的事件和對應(yīng)的節(jié)點
* function.prototype._bindFun[index].type:綁定的事件類型
* function.prototype._bindFun[index].element:綁定的節(jié)點
* 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 = [];
}
// 判斷當(dāng)前的element是否已經(jīng)綁定過該事件
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;
}
}
};
}
})();