每种浏览器都有各自的长处,以及各自的缺点。为了解决跨平台的浏览器的不一致性问题,就得利用客户端检测方法,来突破或者规避种种局限性。
检测web客户端的手段很多,而且各有利弊。但不到万不得已,尽量不要使用客户端检测。只要能找到更通用的方法,就应该优先采用更通用的方法。
一、能力检测
能力检测(又称特性检测)是最常用也是最为人们广泛接受的客户端检测形式。能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。即确定该浏览器是否支持某种方法,其基本模式如下:
if(object.propertyInQuestion){
//使用object.propertyInQuestion
}
举例来说:
function getElement(id){
if (document.getElementById){
return document.getElementById(id);
} else if (document.all){
return document.all[id];
} else {
throw new Error("No way to retrieve element!");
}
}
IE5.0之前的版本不支持document.getElementById()这个Dom方法,尽管可以使用非标准的document.all属性实现相同的目的,但IE的早期版本中确实不存在document.getElementById()。因此,先测试了标准方式是否存在,如果该函数存在,则使用它。否则,继续检测document.all是否存在,如果存在,则使用它。如果两个方法都不存在,则创建并抛出错误,表示这个函数无法使用。
要注意的两个点:
(1)、能力监测时,要先检测达成目的的最常用的特性。先检测最常用的特性可以保证代码最优化,也可以在多数情况下都可以避免测试多个条件。
(2)、能力检测时,必须要测试实际用到的特性。一个特性存在,不代表另一个特性也存在。
1、更可靠的能力检测:
能力检测可以检测出某个特性是否存在,但不能确定该特性是否会按照特定的方式行事,这就需要更可靠的能力检测。举例如下:
//不要这样做,这不是能力检测——只检测了是否存在相应的方法
function isSortable(object){
return !!object.sort
}
这个函数通过检测对象是否存在sort()方法,来确定对象是否支持排序。问题是,任何包含sort属性的对象也会返回true。
var result = isSortable({ sort: true });
检测某个属性是否存在并不能确定对象是否支持排序。更好的方式是检测sort 是不是一个函数。
//这样更好:检查sort 是不是函数
function isSortable(object){
return typeof object.sort == "function";
}
这里的 typeof 操作符用于确定sort 的确是一个函数,因此可以调用它对数据进行排序。
2、能力检测,不是浏览器检测
检测某个或某几个特性并不能够确定浏览器。当通过检测某几个特定的属性来确定浏览器时,实际上是假设该浏览器将来的版本中会继续存在这些属性,以及其他浏览器不会实现这些属性。因此,在实际开发中,应该将能力检测作为确定下一步解决方案的依据,而不是用它来判断用户使用的是什么浏览器。
二、怪癖检测
与能力检测类似,怪癖检测的目标是识别浏览器的特殊行为,其目的是想要知道浏览器存在什么缺陷。例如早期的WebKit中就存在一个怪癖,即它会在for-in循环中返回被隐藏的属性。怪癖检测通常涉及到运行一小段代码,然后确定浏览器是否存在某个怪癖。由于怪癖检测与能力检测相比效率更低,因此应该只在某个怪癖会干扰脚本运行的情况下使用。怪癖检测无法精确地检测特定的浏览器和版本。
三、用户代理检测
通过检测用户代理字符串来识别浏览器。用户代理字符串中包含大量与浏览器有关的信息,包括浏览器、平台、操作系统及浏览器版本。用户代理字符串有过一段相当长的发展历史,在此期间,浏览器提供商试图通过在用户代理字符串中添加一些欺骗性信息,欺骗网站相信自己的浏览器是另外一种浏览器。用户代理检测需要特殊的技巧,特别是要注意opera会隐瞒其用户代理字符串的情况。即便如此,通过用户代理字符串仍然能够检测出浏览器所用的呈现引擎以及所在的平台,包括移动设备和游戏系统。
总结:在决定使用哪种客户端检测方法时,一般应优先考虑使用能力检测。怪癖检测是确定应该如何处理代码的第二选择。而用户代理检测则是客户端检测的最后一种方案,因为这种方法对于用户代理字符串有很强的的依赖性。