浏览器检测是前端开发工作中最常见的问题,有时因为一个属性的不支持,我们需要判断浏览器并对不支持的浏览器做优雅降级。而检测浏览器的方法也有多种,总体来说,我们可以使用js的特性检测(能力检测)或者window对象里的ua、也可以用html的注释、又或者通过css的hack来处理不同浏览器。在实际开发过程中,也需要判断一些属性的支持情况。因为内容比较繁杂,所以在此做个总结。

Javascript

其实在高级程序设计里有提到过,对于浏览器的判断,特性检测的优先级是高于ua检测的。但是,因为现在浏览器版本更新速度都比较频繁,一些浏览器的独有特性不在独有了。说到这里,chrome浏览器虽然是08年发布的,但是由于它的优异表现而被其他各种浏览器模拟。所以说,有时候特性检测并不可靠,而ua则反映的是浏览器的内核、浏览器名称以及版本信息,虽然它会被伪造,但个人还是觉得用它检测是比较靠谱。我整理了一个检测函数:

var browser={
   ua : navigator.userAgent.toLowerCase(),
   detect : function(str){
     var re=new RegExp(str);
     return re.test(this.ua);
   },
   ie : function(){
     return this.detect("msie");
   },
   ie6 : function(){
     return this.detect("msie 6.0");
   },
   ie7 : function(){
     return this.detect("msie 7.0");
   },
   ie8 : function(){
     return this.detect("msie 8.0");
   },
   ie9 : function(){
     return this.detect("msie 9.0");
   },
   ie10 : function(){
     return this.detect("msie 10.0");
   },
   chrome : function(){
     return this.detect("applewebkit")&&this.detect("chrome")&&!this.detect("opr");
   },
   firefox : function(){
     return this.detect("gecko")&&this.detect("firefox");
   },
   opera : function(){
     return this.detect("applewebkit")&&this.detect("opr");
   }
}

这样的话,如果你要判断chrome浏览器,只需这样做即可:

if(browser.chrome()){
  // chrome浏览器才执行的代码
}

当然,你也可以使用jquery中$.browser和$.browser.version来组合判断。

Html

说到html检测浏览器,我们通常都是用html的注释标签来判断浏览器,用它主要是区分IE和非IE浏览器。如果只想要某段代码在IE浏览器生效,我们可以像这样引入一段代码(注意IE需要大写):

<!--[if IE]>
IE浏览器才生效的代码...
<![endif]-->

如上所见,而如果我们需要在非IE浏览器生效,则可以这样引入:

<!--[if !IE]><!--> 
非IE浏览器才生效的代码...
<!--<![endif]-->

如果你要判断不同版本的IE浏览器,只需要在代码中设置IE的版本:

<!--[if IE 6]> 
只要IE6浏览器下才生效的代码...
<![endif]-->

另外,假如你想要设置某个范围内不同版本的IE浏览器,我们可以在html加入相应的判断,小于或等于有lt(less than)、 lte(less than or equal )、 而大于或等于有gt(greater than)、 lte(greater than or equal ):

<!--[if lt IE 8]>
IE8以下浏览器下才生效的代码...
<![endif]-->

<!--[if lte IE 8]>
IE8以及IE8以下浏览器下才生效的代码...
<![endif]-->

<!--[if gt IE 8]>
IE8以上浏览器下才生效的代码...
<![endif]-->

<!--[if gte IE 8]>
IE8以及IE8以上浏览器下才生效的代码...
<![endif]-->

对html5标签,你可以在标签内加入相关标注:

<canvas>
您的浏览器不支持canvas元素
</canvas>

而对于一些html5的功能,如果要在不支持的浏览器使用的话,我们也可以使用modernizr。

Css

对于css判断浏览器,想必我们使用最多的是css hack 。当然你也可以在html判断的基础上相应的引入不同样式文件,但是对于我们只是设置几个元素的独立属性显然是有点杀鸡用牛刀,因此实用性不大。

Css3中的@support

在css3中定义了@support属性,这个属性主要是用于判断某个css属性是否在浏览器支持。support的语法为:

@supports(name:value) {
/* 相关css属性*/
}

让我们来看下具体使用,假设我们要检测box-sizing属性的支持情况:

@supports(box-sizing:content-box)  {
.box{box-sizing:content-box;}
}

当然你也可以组合多个属性来检测:

@supports(box-sizing:content-box) or (background-clip:border-box) {
.box{box-sizing:content-box;background-clip:border-box}
}

JS检测css3属性的支持

由于上面提到的@supports并非所有浏览器支持,而有时我们需要对支持或不支持css3浏览器做相应的处理(比如加个class),因此选择一种通用方法很有必要,在这里,我们使用js和浏览器前缀去判断:

var detectCssSupport = (function() {
var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;

return function(prop) {
// 如果prop是div的可用属性,则浏览器支持,返回true。因为某些属性不用前缀,因此最先判断。
if ( prop in div.style ) return true;

// 将prop(css)属性的首字母转换为大写,类似BoxShadow,浏览器表现为MozBoxShadow // replace第二个参数是第一个参数匹配的结果
prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});

// 加前缀的判断
while(len--) {
if ( vendors[len] + prop in div.style ) {
return true;
}
}
return false;
};
})();

当我们判断某个css属性时,就可以这样。如果支持,就加上相应的类:

if(detectCssSupport("boxShadow")){
   element.className+=” box-shadow”;
}

其他

对于一些css新属性,html、xml标签的浏览器支持情况,你可以查看 http://caniuse.com/

而如果你要判断你现在使用的浏览器是否支持html5标签,你也可以进入这个网址 http://html5test.com/

参考