浏览器检测对于编写使用于多种浏览器的代码是非常有用的。现在JavaScript的形成源自于当初不同的发展脉络,这也在一定程度上解释了为何不同的浏览器对JavaScript有不同的实现形式。诸如向后兼容性,以及由于市场竞争而产生的自然演变等因素,都会导致JavaScript在每种浏览器上的实现有自己的特性。
Navigator对象也称为浏览器对象,该对象包含了浏览器的整体信息,如浏览器名称、版本号等。早期的Netscape浏览器称为Navigator浏览器,Navigator对象是在Navigator浏览器之后命名的。后来Navigator对象成了一种标准, IE 浏览器也支持Navigator 对象。可惜不同的浏览器都自己制定了不同的Navigator对象属性,使得Navigator 对象属性有很多不同。
虽然各种浏览器对Navigator 对象的支持有所不同,但表中的5个Navigator对象的属性是大名数浏览器都支持的属性,这5个属性返回的都是字符串类型的值。
navigator对象的属性
属性 | 说明 |
appName | 返回浏览器名称 |
appVersion | 返回浏览器的版本号 |
userAgent | 返回浏览器用于HTTP请求的用户代理头的值 |
appCodeName | 返回浏览器的代码名 |
platform | 返回运行浏览器的操作系统或硬件平台 |
IE浏览器支持的Navigator对象属性
属性 | 说明 |
cookieEnabled | 检测浏览器是否支持Cookie。该属性值为布尔类型。如果浏览器支持Cookie,则返回true,否则返回false |
systemLanguage | 返回操作系统使用的默认语言,该属性值为字符串 |
userLanguage | 返回用户使用的语言,该属性值为字符串 |
Netscape浏览器支持的Navigator对象属性
属性 | 说明 |
cookieEnabled | 检测浏览器是否支持Cookie,该属性与IE中的cookieEnabled属性相同 |
language | 返回浏览器中使用的默认语言 |
mimeType | 返回一个数组,该数组中的元素代表浏览器支持的MIME类型 |
plugins | 返回一个数组,该数组中的元素代表浏览器已经安装的插件 |
例如:使用Navigator的属性进行浏览器检测,将浏览器的名称和版本号显示出来。
注意:在IE5及以后的版本中,版本号是不正确的,在IE5和IE6中,微软为appVersion字符串赋的值为4.0.需要注意的是,JavaScript在IE6、IE5和IE4中获得的版本号是一样的。
在Netscape浏览器中,Navigator 对象的mimeTypes属性返回的是包含MimeType 对象的数组,plugins属性返回的是包含Plugin对象的数组。因此,MimeType对象与Plugin对象是Navigator对象的子对象
MimeType对象所代表的Netscape浏览器支持MIME类型(数据格式)。这种MIME类型可以是浏览器直接支持的,也可以是由外部程序或插件所支持的.
由于Navigator对象的mimeType属性返回值是一个数组,因此,可以使用一下代码得到MimeType对象:
navigator.mimeTypes[i]
navigator.mimeTypes["typename"]
Plugin对象用来描述Netscape浏览器所安装的插件。在Netscape中,Navigator 对象的plugins属性可以返回Plugin对象的数组,数组中的每个元素 都代表一个浏览器已经安装的插件。Plugin 对象提供的是与插件相关的信息,该信息包括插件名称、说明及插件所支持的MIME类型等。由于plugin属性返回值为数组,所以可以使用以下代码来获得Plugin对象。
navigator.plugins[i]
navigator.plugins["pluginName"]
为了避免JavaScript脚本在一些老版本的浏览器中出现问题,有必要检测一下代码在这些浏览器中是否能够执行。不过通过检测浏览器版本的方法可能得不到想要的结果,因为浏览器以及浏览器版本是经常变化的,所以不可能保证版本总是最新的,并且用户代理(user agent)字符串也可能是伪造的,这些因素都使浏览器的检测比预期的要难得多。
一般对某一浏览器进行检测就是为了确定代码是否可以在客户端上正常运行。那么,要检测脚本是否可以在某浏览器上正常运行,最简单的方法就是检测当前浏览器是否具有脚本中所需的特性,这种检测方法不仅简单,而且比直接检测浏览器更有意义。
浏览器之间的差异可能会导致JavaScript的实现有所差异,也就是说在不同的浏览器中,对于某些特性的实现可能会有些差别,有的浏览器甚至都没有实现这些特性。所以在使用某些函数或者属性之前,首先确定一下它们的存在还是很必要的,这样可以确保所有具有这些特性的浏览器都可以运行用户编写的代码,而那些不具有该特性的自然就被淘汰了。
要检测某些函数和属性在当前使用的浏览器上是否存在,最简单的方法就是使用typeof操作符。通过向该操作符传递JavaScript值、对象、类、方法或者属性,就可以确定该操作符的类型。例如,向typeof传递一个当前浏览器中不存在的操作符,那么得出的结果就是udefined类型。
例如,可以检测一下当前的浏览器是否支持XMLHtpRequest类,具体实现如下:
var xmIExists=typeof XML HttpRequest;
在Mozilla、Opera8 或者Safari 1.2中,变量xmlExists的值将是object或者function, 而在IE6以及其他更老版本的浏览器中,其值将是undefined.
这种方法还适用于函数、方法以及属性和类的检测。当检测函数和方法时,需要省去函数名或方法名后面附带的内容,否则脚本会试图去识别该函数或方法的返回值的类型,如果该函数或者方法不存在,将会导致错误发生:
var getExists=typeof document.getElementByld;
借助这种测试方法还可以为那些不支持某些特性的训览器提供相应的代码
if(typeof document.designModel!=undefined){
document.designMode="on";
}else{
return false;
}
如果对CSS比较熟悉,则对Quirks模式和标准模式也会很熟悉。当前主流的浏览器都使用这两种模式对页面做不同的处理,而且应用这两种模式时,可能采用老版本浏览器所使用的规则,或者采用更新的符合标准的规则。使用的模式不同会影响到页面的显示效果,所以在改变页面元素的尺寸之前,先搞清楚浏览器使用的模式。
通过读取document.compatMode属性就可以确定浏览器处理文档时使用的是标准模式还是Quirks模式。如果使用的是Quirks模式,大多数浏览器都会给这个属性赋值为BackCompat (不过Opera赋值为QuirksMode) ;而如果使用的是标准模式,则将返回CSSICompat (目前是这样的)。基于这一点,一个可靠的测试方法就是检测CSSICompat,如果没有返回值,则认为浏览器使用的是Quirks模式。
function QuirksMode(){
if(typeof document.compatMode !="undefined" &&/CSS.Compat/.test(document.compatMode)){
return false;
}
return true;
}
如果文档是使用Quirks模式渲染的,那么QuirksMode将返回true,否则将返回false.
使用的是哪种模式会在页面的DOCTYPE声明中体现出来,对于没有DOCTYPE的HTML文档,将自动按照Quirks模式进行处理,但是有DOCTYPE并不意味着文档一定用Quirks模式渲染。
两种模式之间的大部分区别都跟CSS相关,所以如果JavaScript需要对元素的样式进行处理,则还需要对CSS规则进行适当的处理。相对而言,Quirks 模式一般来说比较宽松,对某些规则并不强求,不过两者最重要的区别可能是盒模型计算中的差异,尤其是元素尺寸计算的方式。
如果将DOCTYPE从页面上删除,对JavaScript的执行没有什么影响,唯受影响的浏览器就是IE6,该浏览器将会重新整理用于确定窗口和页面尺寸的某些属性值。
本篇文章主要是关于了解浏览器的几种方法及浏览器检测对象,检测浏览器的目的是使脚本能够顺利地工作。具体可以参考《JavaScript从入门到精通》(第二版)一书。