浏览器提供商虽然在实现公共接口方面投入了很多精力,但结果仍然是每一种浏览器都有各自的长处,也都有各自的缺点。即使是那些跨平台的浏览器,虽然从技术上看版本相同,也照样存在不一致性问题。面对普遍存在的不一致性问题,开发人员要么采取迁就各方的“最小公分母”策略,要么(也是更常见的)就得利用各种客户端检测方法,来突破或者规避种种局限性。
迄今为止,客户端检测仍然是Web开发领域中一个饱受争议的话题。一谈到这个话题,人们总会不约而同地提到浏览器应该支持一组最常用的公共功能。在理想状态下,确实应该如此。但是,在现实当中,浏览器之间的差异以及不同浏览器的“怪癖”( quirk),多得简直不胜枚举。因此,南昌网站建设公司开发工程师认为,客户端检测除了是一种补救措施之外,更是一种行之有效的开发策略。
检测Web客户端的手段很多,而且各有利弊。但最重要的还是要知道,不到万不得已,就不要使用客户端检测。只要能找到更通用的方法,就应该优先采用更通用的方法。一言以蔽之,先设计最通用的方案,然后再使用特定于浏览器的技术增强该方案。
客户端能力检测
最常用也最为人们广泛接受的客户端检测形式是能力检测(又称特性检测)。能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。采用这种方式不必顾及特定的浏览器如何如何,只要确定浏览器支持特定的能力,就可以给出解决方案。能力检测的基本模式如下:
if (obj ect .propertyInQuestion)(
//使用o]oj ect.propertyInQuestion
)
举例来说,lE 5.0之前的版本不支持document.getElementsByld()这个DOM方法。尽管可以使用非标准的doclunent.all属性实现相同的目的,但IE的早期版本中确实不存在document.getElementsByld()。于是,也就有了类似下面的能力检测代码:
function getElement( id)t
if (document.getElementByld)(
return document.getElementByld( id);
} else if( document.all){
return document.all[id];
} else{
throw new Error( "No way to retrieve element!”);
}
}
这里的getElement()函数的用途是返回具有给定ID的元素。南昌网站设计公司技术员告诉大家,因为document.getElementByld()是实现这一目的的标准方式,所以一开始就测试了这个方法。如果该函数存在(不是未定义),则使用该函数。否则,就要继续检测document.all是否存在,如果是,则使用它。如果上述两个特性都 不存在(很有可能),则创建并抛出错误,表示这个函数无法使用。
要理解能力检测,首先必须理解两个重要的概念。如前所述,第一个概念就是先检测达成目的的最常用的特性。对前面的例子来说,就是要先检测document.getElementByld(),后检测document.all。先检测最常用的特性可以保证代码最优化,因为在多数情况下都可以避免测试多个条件。
第二个重要的概念就是必须测试实际要用到的特性。一个特性存在,不一定意味着另一个特性也存在。来看一个例子:
function getWindowWidth(){
if(document.all){//假设是IE
return document.do cumentElement.clientWidth://错误的用法!!!
} else{
return window.innerWidth;
}
}
这是一个错误使用能力检测的例子。getWindowWidth()函数首先检查document.all是否存在,如果是则返回document.documentElement.clientWidth,第8章曾经讨论过,IE确实不支持window.innerWidth属性。但问题是document.all存在也不一定表示浏览器就是IE。实际上,也可能是Opera; Opera支持document.all,也支持window.innerWidth。
检测某个或某几个特性并不能够确定浏览器。下面给出的这段代码(或与之差不多的代码)可以在许多网站中看到,这种“浏览器检测”代码就是错误地依赖能力检测的典型示例:
//错误!还不够具体
var isFirefox=!!(navigator.vendor&&navigator.vendorSub);
//错误!假设过头了
var isIE= !!(document.all&&document.uniqueID);
这两行代码代表了对能力检测的典型误用。以前,确实可以通过检测navigator.vendor和navigator.vendorSub来确定Firefox浏览器。但是,Safari也依葫芦画瓢地实现了相同的属性。于是,这段代码就会导致人们作出错误的判断。为检测IE,代码测试了document.all和document.uniqueID。这就相当于假设IE将来的版本中仍然会继续存在这两个属性,同时还假设其他浏览器都不会实现这两个属性。最后,这两个检测都使用了双逻辑非操作符来得到布尔值(比先存储后访问的效果更好)。
实际上,根据浏览器不同将能力组合起来是更可取的方式。如果你知道自己的应用程序需要使用某些特定的浏览器特性,那么最好是一次性检测所有相关特性,而不要分别检测。看下面的例子:
//确定浏览器是否支持Netscape风格的插件
var hasNSPlugins= !!(navigator.plugins&&navigator.plugins.length);
//确定浏览器是否具有DOMI级规定的能力
var hasDOMl= !!(document.getElementByld&&document.createElement&&
document.getElementsByTagName);
以上例子展示了两个检测:一个检测浏览器是否支持Netscapte风格的插件;另一个检测浏览器是否具备DOMI级所规定的能力。得到的布尔值可以在以后继续使用,从而节省重新检测能力的时间。
南昌网络公司工程师提醒广大开发人员,在实际开发中,应该将能力检测作为确定下一步解决方案的依据,而不是用它来判断用户使用的是什么浏览器.
本文仅限内部技术人员学习交流,不得作于其他商业用途.文章出自:南昌网站建设公司-百恒网络 https://www.jxbh.cn 如转载请注明出处!