做前端开发时常需要考虑浏览器的兼容性,通常采用的是判断该对象有没有这个属性,如果有就直接使用内置的属性,如果没有就使用自己构建的属性。
例如在IE8下就不能使用getElementsByClassName()这个函数,我们通常会采用如下做法。
if(document.getElementsByClassName){
var dom = document.getElemensByClassName(className);
//...
}else{
//调用自己写的方法
}
性能提升
对于如上的做法,能实现浏览器兼容性判断,但是对于每次调用document.getElementsByClassName()都需要去原型中检索,势必会影响效率,对于dom中的方法,可能需要检索几层原型。通常的做法是另外建立一个对象,在框架初始化的时候,就判断浏览器的兼容性,让后将对应属性是否兼容该浏览器添加的该对象中。
写法如下,这里以getElementsByClassName()为例。
var support = {};
support.getElementsByClassName = !!document.getElementsByClassName;
!!的意思是将其转换程boolean类型。否则存放的就是对getElementsByClassName的引用。
更严谨的判断
我们思考这样一种情况,假设浏览器中存在getElementsByClassName这个属性,但是这个属性不是一个Function,或者是一个Function,但这个Function并不能满足我们程序原本的需求,当我们调用的时候就会产生异常。
如何解决这个问题?JQuery中采取的办法是构建一个div,然后给div添加className属性之后,然后再进行通过该方法获取到div,如果能够获取到div,就证明该方法是有效的。
var support = {};
support.getElementsByClassName = (function(){
var isExist = !!document.getElementsByClassName;
if(isExist && typeof document.getElementsByClassName == "function"){
var div = document.createElement("div");
var div2 = document.createElement("div");
div2.className = "box";
div.appendChild(div2);
var _div = div.getElementsByClassName("box")[0];
return div2 === _div;
}
})();
那如果浏览器中的getElementsByClassName属性不存在,我们就调用自己写的函数,这个函数写法如下:
var getDomByClass = function(className){
if(support.getElementsByClassName){
return document.getElementsByClassName(className);
}else{
var doms = document.getElementsByTagName("*");
var temp = [];
for (var i = 0; i<doms.length;i++) {
//加上空格是为了避免匹配到某个属性的一部分,例如class = "aaa b",我们传递的是a也能匹配
if((" " + doms[i].className + " ").indexOf(" "+className + " ") != -1){
temp.push(doms[i]);
}
}
return temp;
}
};