写js最常见的场景就是不断兼容各个版本的浏览器了。其中,又以IE系列最让人心塞,虽然jquery在早期解决了额不少麻烦,但是随着近期jquery逐渐淡出,那么原生的兼容方法就比较重要了。
众所周知,IE8是一个分水岭,除了IE8及其以下的浏览器意外,chrome、Firefox都基本支持以addEventListener
方法来注册事件,以removeEventListener
来解除事件。
然而,在IE8以下却不能这样,注册事件是用attachEvent
,而解除事件则是用detachEvent
,因此,有相当比较旧的项目在维护或新增功能时,就不得不自己写一套兼容的事件处理代码了,参照:
var EventUtil = {
addHandler:function(element,type,handler){
//绑定事件
//Chrome Firefox IE9等 addEventListener
//IE8及IE8以下的浏览器 attachEvent
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if (element.attachEvent) {
element.attachEvent("on"+ type,handler);
} else{
element["on"+type] = handler
}
},
removeHandler: function(element,type,handler){
//移除事件
//Chrome Firefox IE9等
//IE8及IE8以下的浏览器
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if (element.detachEvent) {
element.detachEvent("on"+type,handler);
} else{
element["on"+type] = handler
}
}
}
另外,由于在事件注册中,我们最常使用到的就是event对象,而这个对象在IE8以下的浏览器中,获取的方法和主流浏览器略有不同,因此也可以一并写到整个跨浏览器处理事件中:
getTarget: function(event) {
return event.target || event.srcElement;
},
在addEventListener
中,另一个常用的技巧是冒泡机制以及对浏览器元素默认行为的控制,这两个行为在也是以IE8为分水岭分成了两种代码,因此也需要做兼容处理:
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation()
} else {
event.cancelBubble = true;
}
}
preventDefault: function(event) {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
关于整个js时间的跨浏览器处理,可以抽象成一个对象来封装,最后的代码如下:
var EventUtil = {
addHandler: function(element, type, handler) {
//绑定事件
//Chrome Firefox IE9等 addEventListener
//IE8及IE8以下的浏览器 attachEvent
if(element.addEventListener) {
element.addEventListener(type, handler, false);
} else if(element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler
}
},
removeHandler: function(element, type, handler) {
//移除事件
//Chrome Firefox IE9等
//IE8及IE8以下的浏览器
if(element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if(element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = handler
}
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event) {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation()
} else {
event.cancelBubble = true;
}
}