8.3 navigator对象
最早由Netscape Navigator 2.0 引入的navigator对象,现在已经成为识别客户端浏览器的事实标准。虽然其他浏览器也通过其他方式提供了相同或者相似的信息(例如,IE中的window.clientInformation和Opera中的window.opera),但navigator对象却是所有支持JavaScript的浏览器所共有的。
表中这些navigator对象的属性通畅用于检测显示网页的浏览器类型。
1. 检测插件
检测浏览器是否安装了特定的插件是一种最常见的检测例程。对于非IE浏览器,可以使用plugins数组来达到这个目的。
- name: 插件的名字。
- description: 插件的描述。
- filename: 插件的文件名
- length: 插件所处理的MIME类型数量。
一般来说,name属性中包含检测插件必须的所有信息,但有时候也不完全如此。在检测插件时,需要像下面这样循环迭代每个插件的name与给定的名字进行比较。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//检测插件(在IE中无效)
function hasPlugin(name){
name = name.toLowerCase();
for(var i = 0; i < navigator.plugins.length; i++){
if(navigator.plugins[i].name.toLowerCase().indexOf(name) > -1) {
return true;
}
}
return false;
}
//检测Flash
console.log(hasPlugin('Flash'));
//检测QuickTime
console.log(hasPlugin('QuickTime'));
比较的字符串最好都使用小写形式,这样可以避免大小写不一致导致检测错误。而传入的参数应该尽可能具体,以避免混淆。在Firefox、Safari、Opera和Chrome中可以使用这种方法来检测插件。
每个插件对象本身也是一个MimeType对象的数组,这些对象可以通过方括号语法来访问。每个MimeType对象有4个属性:包含MIME类型描述的description、回指插件对象的enabledPlugin、表示与MIME类型对应的文件扩展名的字符串suffixes(以逗号分隔)和表示完整MIME类型字符串的type。
检测IE中的插件比较麻烦,因为IE不支持Netscape式的插件。在IE中检测插件的唯一方式就是使用专有的ActiveXObject类型,并尝试创建一个特定插件的实例。IE是以COM对象的方式实现插件的,而COM对象使用唯一标识符来标识。因此,要想检查特定的插件,就必须知道其COM标识符。
例如,Flash标识符石ShockwaveFlash.ShockwaveFlash。知道唯一标识符之后,就可以编写类似下面的函数来检测IE中是否安装相应插件了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//检测IE中的插件
function hasIEPlugin(name){
try {
new ActiveXObject(name);
return true;
} catch(ex) {
return false;
}
}
//检测Flash
console.log(hasIEPlugin('Flash'));
//检测QuickTime
console.log(hasIEPlugin('QuickTime'));
之所以要在try-catch语句中进行实例化,是因为创建未知的COM对象会抛出错误。这样,如果实例化成功,则函数返回true;否则,抛出了错误则返回false。
鉴于两种检测方法差别太大,可以针对每个插件分别创建检测函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function hasPlugin(name){
name = name.toLowerCase();
for(var i = 0; i < navigator.plugins.length; i++){
if(navigator.plugins[i].name.toLowerCase().indexOf(name) > -1) {
return true;
}
}
return false;
}
function hasIEPlugin(name){
try {
new ActiveXObject(name);
return true;
} catch(ex) {
return false;
}
}
//检测所有浏览器中的Flash
function hasFlash(){
var result = hasPlugin('Flash');
if(!result) {
result = hasIEPlugin('Flash');
}
return result;
}
console.log(hasFlash());
plugins集合有一个名叫refresh()的方法,用于刷新plugins以反映罪行安装的插件。这个方法接收一个参数:表示是否应该重新加载页面的一个布尔值。如果是true,则重新加载包含插件的所有页面;否则,只更新plugins集合,不重新加载页面。
2. 注册处理程序
Firefox2 为navigator对象新增了registerContentHandler()和registerProtocolHandler()方法(这两个方法是在HTML5定义的)。这两个方法可以让一个站点指明它可以处理特定类型的信息。随着RSS阅读器和在线电子邮件程序的兴起,注册处理程序就为像使用桌面应用程序一样默认使用这些在线应用程序提供了一种方式。
其中registerContentHanlder()接收三个参数:要处理的MIME类型、可以处理该MIME类型的页面的URL以及应用程序的名称。例如,要将一个站点注册为处理RSS源的处理程序,可以使用如下代码:
1
2
//##skipEval
navigator.registerContentHandler('application/rss+xml', 'http://www.somereader.com?feed=%s', 'Some Reader');
%s表示RSS源的URL。当下一次请求RSS源时,浏览器就会打开指定的URL,而相应的Web应用程序将以适当方式来处理该请求。
Firefox4及之前的版本只允许在registerContentHandler()方法中使用三个MIME类型:application/rss+xml、application/atom+xml和application/vnd.mozilla.feed。这三个MIME类型的作用都一样,即为RSS或者ATOM新闻源(feed)注册处理程序。
类似的调用方式也适用于registerProtocolHandler()方法,它也接收三个参数:要处理的协议(例如mailto或ftp)、处理该协议的页面的URL和应用程序的名称。例如,要想将一个应用程序注册为默认的邮件客户端,可以使用如下代码:
1
2
//##skipEval
navigator.registerProtocolHandler('mailto', 'http://www.somemailclient.com?cmd=%s', 'Some Mail cleint');
这个例子注册了一个mailto协议的处理程序,该程序指向一个基于Web的电子邮件客户端。同时,第二个参数仍然是处理相应请求的URL,而%s则表示原始的请求。
【本文内容摘自:《JavaScript高级程序设计》(第3版)Nicholas C.Zakas 著 李松峰 曹力 译】