本文整理JavaScript中跨浏览器事件处理的核心方法,涵盖事件绑定与移除、默认行为阻止、目标对象获取及窗口尺寸查询。通过封装统一接口,解决不同浏览器对addEventListener、attachEvent等API支持的差异,确保代码在主流浏览器中兼容运行。
事件绑定与移除机制
在Web开发中,为元素绑定事件是基础操作。为了实现跨浏览器兼容,需要封装统一的处理函数。该函数首先检测浏览器是否支持DOM2级标准事件方法addEventListener,若支持则直接调用;其次检查是否支持IE特有的attachEvent方法,若支持则通过添加'on'前缀的方式注册事件;最后若两者均不支持,则采用DOM0级方式,直接将事件处理函数赋值给元素的对应属性。这种方式确保了在不同版本的浏览器中都能正确绑定事件。
EU.addHandler = function(element,type,handler){
//DOM2级事件处理,IE9也支持
if(element.addEventListener){
element.addEventListener(type,handler,false);
}
else if(element.attachEvent){
//type加'on'
//IE9也可以这样绑定
element.attachEvent('on' + type,handler);
}
//DOM0级事件处理步,事件流也是冒泡
else{
element['on' + type] = handler;
}
};
取消事件绑定的逻辑与绑定过程基本对称,但有一个关键注意事项:在移除事件时,传入的处理函数必须与绑定事件时传入的函数完全相同,即指向内存中的同一个函数对象。如果引用不一致,浏览器将无法正确移除事件监听器。具体实现上,若支持removeEventListener则调用该方法;若支持IE的detachEvent则调用之;对于不支持上述方法的旧式浏览器,只需将对应的事件属性设置为null即可实现解绑。
EU.removeHandler = function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler);
}
else if(element.attachEvent){
element.detachEvent('on' + type,handler);
}
else{
//属性置空就可以
element['on' + type] = null;
}
};
跨浏览器事件添加与移除封装
跨浏览器添加事件的通用封装函数通常名为addEvent。该函数接收对象、事件类型和处理函数作为参数。首先判断对象是否具备addEventListener方法,这是W3C标准推荐的方式,因此优先使用。如果不支持,则回退到IE浏览器的attachEvent方法,注意此时事件类型需要加上'on'前缀。这种判断逻辑保证了代码在现代标准浏览器和旧版IE浏览器中的可用性。
function addEvent(obj,type,fn){
if(obj.addEventListener){
obj.addEventListener(type,fn,false);
}else if(obj.attachEvent){//IE
obj.attchEvent('on'+type,fn);
}
}
跨浏览器移除事件的处理函数removeEvent同样遵循优先使用标准API的原则。它首先检查对象是否拥有removeEventListener方法,若存在则直接调用以移除指定的事件监听器。若该方法不存在,则尝试使用IE特有的detachEvent方法,同样需要注意事件类型前缀的处理。通过这种分层判断,实现了在不同浏览器环境下安全地移除事件绑定。
function removeEvent(obj,type,fn){
if(obj.removeEventListener){
obj.removeEventListener(type,fn,false);
}else if(obj.detachEvent){//兼容IE
obj.detachEvent('on'+type,fn);
}
}
默认行为与目标对象处理
阻止事件的默认行为在不同浏览器中存在差异。封装函数preDef接收事件对象作为参数,首先兼容处理非标准浏览器环境,将window.event赋值给局部变量e。接着检测e是否具备preventDefault方法,若具备则调用该方法以阻止默认行为;否则,对于旧版IE浏览器,通过将returnValue属性设置为false来实现相同的效果。这种写法确保了链接跳转、表单提交等默认动作能被正确拦截。
function preDef(ev){
var e = ev || window.event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue =false;
}
}
获取触发事件的目标对象时,不同浏览器提供了不同的属性。封装函数getTarget首先检查事件对象是否包含target属性,这是W3C标准规范,若存在则直接返回该属性值。若不存在,则回退到IE浏览器的机制,通过window.event.srcElement获取触发事件的具体元素。这种判断逻辑确保了无论在标准浏览器还是IE浏览器中,都能准确获取到事件的源对象。
function getTarget(ev){
if(ev.target){//w3c
return ev.target;
}else if(window.event.srcElement){//IE
return window.event.srcElement;
}
}
滚动位置与窗口尺寸获取
跨浏览器获取滚动条位置需要处理不同文档模式下的差异。封装函数getSP返回一个包含top和left属性的对象。对于垂直滚动位置,优先获取document.documentElement.scrollTop,若为0则回退到document.body.scrollTop;水平滚动位置同理,优先获取document.documentElement.scrollLeft,否则使用document.body.scrollLeft。这种||运算符的使用方式有效兼容了标准模式和怪异模式下的滚动位置获取。
//跨浏览器获取滚动条位置,sp == scroll position
function getSP(){
return{
top: document.documentElement.scrollTop || document.body.scrollTop,
left : document.documentElement.scrollLeft || document.body.scrollLeft;
}
}
获取可视窗口大小的封装函数getWindow首先检测window.innerWidth是否已定义,若已定义则直接返回window对象的innerWidth和innerHeight属性值,这适用于大多数现代标准浏览器。若该属性未定义(如旧版IE),则回退到获取document.documentElement的clientWidth和clientHeight。这种判断机制确保了在不同浏览器环境下都能准确获取到当前可视区域的大小。
function getWindow () {
if(typeof window.innerWidth !='undefined') {
return{
width : window.innerWidth,
height : window.innerHeight
}
} else{
return {
width : document.documentElement.clientWidth,
height : document.documentElement.clientHeight
}
}
},