本文提供一段JavaScript库封装代码,旨在解决不同浏览器间事件注册与移除的差异。通过判断addEventListener与attachEvent的支持情况,分别处理标准浏览器与IE8及以下版本。针对IE特有的this指向window问题,通过包装函数实现this指向修正,并采用数组存储事件引用以支持移除匿名事件及防止重复注册。
直接查看实现代码:
具体实现如下:
事件注册与移除的跨浏览器封装实现(function(){
// 执行库封装逻辑,避免全局对象污染
window['cm']={};
/**
/**
* 为指定对象注册事件监听器
*/
var addListener=function(element,type,fn){
if(typeof element == 'undefined') return false;
if(element.addEventListener){
element.addEventListener(type,fn,false);
}else if(element.attachEvent){
// 将事件引用缓冲存储至该元素对象上,此处理解决了IE中this指向window的问题(现fn内this正确指向element)以及移除匿名事件函数的难题
var _EventRef='_'+type+'EventRef';
if(!element[_EventRef]){
element[_EventRef]=[];
}
var _EventRefs=element[_EventRef];
var index;
for(index in _EventRefs){
if(_EventRefs[index]['realFn']==fn){
return;
}
}
var nestFn=function(){
fn.apply(element,arguments);
};
element[_EventRef].push({'realFn':fn,'nestFn':nestFn});
element.attachEvent('on'+type,nestFn);
}else{
element['on'+type]=fn;
}
};
window['cm']['addListener']=addListener;
/**
/**
* 移除对象上已注册的事件监听
*/
var removeListener=function(element,type,fn){
if(typeof element == 'undefined') return false;
if(element.removeEventListener){
element.removeEventListener(type,fn,false);
}else if(element.detachEvent){
var _EventRef='_'+type+'EventRef';
if(!element[_EventRef]){
element[_EventRef]=[];
}
var _EventRefs=element[_EventRef]
var index;
var nestFn;
for(index in _EventRefs){
if(_EventRefs[index]['realFn']==fn){
nestFn=_EventRefs[index]['nestFn'];
if(index==_EventRefs.length-1){
element[_EventRef]=_EventRefs.slice(0,index);
}else{
element[_EventRef]=_EventRefs.slice(0,index).concat(_EventRefs.slice(index+1,_EventRefs.length-1));
}
break;
}
}
if(nestFn){
element.detachEvent('on'+type,nestFn);
}
}else{
element['on'+type]=null;
}
};
})();