supce's blog

客户端检测

不同浏览器之间或者相同浏览器不同版本之间存在着不一致性问题,可以使用客户端检测来解决不一致性带来的兼容问题。


能力检测 (特性检测)

能力检测不是用来识别特定的浏览器,而是识别浏览器的能力。它并不关心用户使用的是什么浏览器,该方法只要确定浏览器支持某种特定的功能,就可以根据该功能提出解决方案。

if(object.someProperty){
    //do something
}
//确定浏览器是否具有DOM1级规定的能力
var hasDOM1 = !!(document.getElementById && document.createElement && document.getElementsByTagName);
console.log(hasDOM1);

能力检测作为确定下一步解决方案的依据,而不是用它来判断用户使用的是什么浏览器。


怪癖(quirk)检测

怪癖检测主要是想知道浏览器存在哪些缺陷,通常会运行一小段代码,以确定浏览器的某个特性不能正常工作。
比如:IE8及更早版本与其他浏览器处理空白字符的方式不一样,IE9之前的版本不会为空白符创建节点

<ul id="test">
    <li>item 1</li>
    <li>item 2</li>
    <li>item 3</li>
</ul>
<script type="text/javascript">
    var myList = document.getElementById("test");
    var copyList = myList.cloneNode(true);
    console.log(copyList.childNodes.length); 
</script>

上面的代码中,IE<9时,长度为3,而其他浏览器为7

IE7及以下版本有一个有意思的怪癖:name特性与给定ID匹配的表单元素(<input>,<textarea>,<button>及<select>)也会被该方法返回

<input type="text" name="myElement" value="Text" />
<div id="myElement">div</div>
<script type="text/javascript">
    alert(document.getElementById("myElement"));
</script>

IE<8返回的是input,其他浏览器返回的为div

还有书上的一个例子:IE8及更早版本中存在一个bug,即如果某个实例属性与[[Enumerable]]标记为false的某个原型属性同名,那么该实例属性将不会出现在for—in循环当中


用户代理检测

用户代理检测主要是用来检测用户具体是什么浏览器、什么呈现引擎(内核)、什么版本、什么平台。
常见的浏览器内核分别为:

  • Gecko (Firefox)
  • WebKit (Safari)
  • Blink (Opera Chrome)
  • Trident (IE)
    括号内为对应的浏览器

完整的用户代理检测脚本在高级程序第九章中,这里就不贴了