当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

JavaScript 客户端检测——“能力检测”的注意要点 - 前端学习笔记

作者:小梦 来源: 网络 时间: 2024-06-17 阅读:

客户端检测

不到万不得已,就不要使用客户端检测。只要能够找到更通用的方法,就应该优先采用更通用的方法。先设计最通用的方案,然后再使用特定于浏览器的技术增强该方案。

能力检测(性能检测)

基本模式语法

目标不是识别特定的浏览器,而是识别浏览器的能力。基本模式如下:

if (object.propertyInQuestion){    //使用object.propertyInQuestion}

举个例子,比如 IE5.0 之前的版本不支持 document.getElementById() 这个 DOM 方法。但可以使用 document.all[] 方法。于是可以写下如下代码:

function getElement(id){    if (document.getElementById){        return document.getElementById(id);    }else if (document.getAll){        return document.getAll[id];    }else{        throw new Erroor("No way to retrieve element !");    }}

能力检测使用的要点

  1. 先检测达成目的的最常用的特性,可以保证代码最优化,并避免检测多个条件;

  2. 必须测试实际要是用到的特性;

对于第二点:

function getWindowWidth(){    if (document.all){ //假设是 IE 浏览器        return document.documentElement.clientWidth; //错误!不一定是 IE 浏览器    } else {        return window.innerWidth;    }}

如Opera 支持document.all,也支持window.innerWidth;所以上述代码用法上有问题。

更可靠的能力检测

能力检测对于想知道某个特性是否会按照适当方式行事非常有用。如检测对象是否支持排序:

function isSortable(obj){    return typeof obj.sort == "function";}var obj1 = [321,43215,1];var obj2 = {    name: "Oliver",    age: 18};console.log(isSortable(obj1)); //trueconsole.log(isSortable(obj2)); /false

这里需要注意的是,能力检测不是只检测相应的方法是否存在!!!

function isSortable(obj){    return !!obj.sort;}var obj1 = [321,43215,1];var obj2 = {    name: "Oliver",    age: 18,    sort: true};console.log(isSortable(obj1)); //trueconsole.log(isSortable(obj2)); //true

这里就可以看出问题了,能力检测不是检测相应的方法是否存在,obj2 中定义了 sort 属性,仍然可以通过所谓的能力检测检测为 true。

所以在可能的情况下,要尽量使用 typeof 进行能力检测。

而在 IE 中,情况又不同了:

function hasCreateElement(){    return typeof document.createElement == "function";}

在 IE8 之前,这个函数返回 false,因为 typeof document.createElement 返回的是"object",而不是“function”。因为 IE 及更早版本中的宿主对象是通过 COM 而非 JScript 实现的。但 IE9 中纠正了这个问题,对所有 DOM 方法都返回“function”。

能力检测,不是浏览器检测

在实际开发中,应该将能力检测作为确定下一步解决方案的依据,而不是用他来判断用户使用的是什么浏览器。如:

var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);var hasDOM1 = !!(document.getElementById && document.getElementsByTagName && document.createElement);

上述代码一个是用来确定浏览器是否支持 Netscapte 风格的插件;另一个是用来确定浏览器是否具备 DOM1 级所规定的能力。

怪癖检测

目标是识别浏览器的特殊行为。怪癖检测是想要知道浏览器存在什么缺陷。如,IE8 及更早版本中存在一个 bug,即如果某个实例属性与[[Enumerable]]标记为 false 的某个原型属性同名,那么该实例就不会出现在 for-in 循环当中。可以使用以下代码来检测这种“怪癖”:

var hasDontEnumQuirk = function(){    var o = { toString : function(){} };    for (var prop in o){        if (prop == "toString"){return false;        }    }    return true;}();

另外,在 Safari 3 以前的版本中会枚举被隐藏的属性。可以用下面的函数来检测:

var hasEnumShadowsQuirk = function(){    var o = { toString : function(){} }    var count = 0;    for (var prop in o){        if (prop == "toString"){count++;        }    }    return (count > 1);}();

如果浏览器存在这个 bug,那么使用 for-in 循环枚举带有自定义的 toString() 方法的对象,就会返回两个 toString 的实例。

热点阅读

网友最爱