jQuery.browser的实现方式

jQuery.browser的实现方式
jQuery中的browser对象

jQuery中的browser对象保存了浏览器的信息。跨浏览器是大多数客户端JS库必须具备的基本特性,判断浏览的类型和版本号并保存在对象中,就是为了针对不同浏览器采取不同的策略。

下面的代码用于展示jQuery.browser的用法:

<script type="text/javascript" src="jquery.js"></script>
<script>
document.write('$.browser.webkit: ' + $.browser.webkit + '<br />');
document.write('$.browser.opera: ' + $.browser.opera + '<br />');
document.write('$.browser.msie: ' + $.browser.msie + '<br />');
document.write('$.browser.mozilla: ' + $.browser.mozilla + '<br />');
document.write('$.browser.version: ' + $.browser.version);
</script>

这段代码在不同浏览器中的显示效果是不同的。

IE中的显示效果如下:

$.browser.webkit: undefined
$.browser.opera: undefined
$.browser.msie: true
$.browser.mozilla: undefined
$.browser.version: 8.0

根据$.browser.msie是否为true,就可以判断浏览器是否为IE内核了。而通过$.browser.version可以获得浏览器内核的版本号。其他浏览器可以采用类似的方式进行判断。

实现思路

jQuery.browser的实现思路如下:

1.通过window.navigator.userAgent获取浏览器的描述字符串

2.使用正则表达式进行匹配,不同浏览器内核对应正则表达式是不同的

3.根据匹配的结果,判断是否为特定浏览器,并提取版本号

4.将结果保存到browser对象中。

  首先,让我们测试一下不同浏览器的 window.navigator.userAgent 的输出结果:
ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua);

GoogleChrome的显示结果:

user agent:
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24

我们知道Cheomr的浏览器内核是Webkit,因此其中最重要的是WebKit关键字,但GoogleChrome为了显示其兼容性,也在描述字符串中包含了Mozilla等字样。其他浏览器也有类似的情况。

AppleSafari的显示结果:

user agent:
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1

MicrosoftIE8.0的显示结果:

user agent:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)

MozillaFireFox的显示结果:

user agent:
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

Opera的显示结果:

user agent:
Opera/9.80 (Windows NT 6.1; U; Edition IBIS; zh-cn) Presto/2.8.131 Version/11.10

因为不同浏览器采用的正则表达式是不同的,下面,我们就针对不同的浏览器的情况,对jQuery.browser的实现进行进一步的分析。

Webkit 内核的检测

GoogleChrome和AppleSafari使用的都是Webkit内核,其描述字符串中也都包含了"Webkit",因此用于检测的正则表达式中需要包含"Webkit"。

另外,版本号是紧跟着"Webkit"关键字的,中间用"/"分隔。因此,我们可以用下面的代码判断浏览器是否为Webkit内核,并提取版本号:

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /WebKit\/([\w.]+)/.exec(ua);
if (match) {
	document.write('Webkit Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Webkit Kernal');
}

使用的正则表达式是/WebKit\/([\w.]+)/,表示包含"Webkit"及分隔符"/",并且捕捉"/"之后的字符,直到空格为止,作为版本号。(\w匹配字母或数字或下划线或汉字等。)

IE 内核的检测

IE内核浏览器的描述字符串中包含了"MSIE",版本号紧跟着"MSIE"关键字,中间用空格分隔。因此,我们可以用下面的代码判断浏览器是否为IE内核,并提取版本号:

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /MSIE ([\w.]+)/.exec(ua);
if (match) {
	document.write('IE Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not IE Kernal');
}

使用的正则表达式是/MSIE([\w.]+)/,表示包含"MSIE"及空格,并且捕捉空格之后的字符,直到下一个空格为止,作为版本号。

Mozilla 内核的检测

MozillaFirefox描述字符串中包含了"Mozilla",版本号出现在在"rv:"之后(Mozilla关键字之后也有版本号,但rv之后的版本号更细化一些)。因此,我们可以用下面的代码判断浏览器是否为Mozilla内核,并提取版本号:

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /Mozilla(?:.*? rv:([\w.]+))/.exec(ua);
if (match) {
	document.write('Mozilla Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Mozilla Kernal');
}

使用的正则表达式是/Mozilla(?:.*?rv:([\w.]+))/,表示包含"Mozilla",并且捕捉"rv:"之后的字符,直到下一个空格为止,作为版本号。

Opera 内核的检测

Opera描述字符串中包含了"Opera",版本号出现在在"Version/"之后(同样,Opera关键字之后也有版本号,但"Version"之后的版本号更细化一些)。因此,我们可以用下面的代码判断浏览器是否为Opera内核,并提取版本号:

ua = window.navigator.userAgent;
document.write('user agent:<br />' + ua + '<br /><br />');

match = /Opera(?:.*Version)\/([\w.]+)/.exec(ua);
if (match) {
	document.write('Opera Kernal<br />');
	document.write('Version: ' + match[1]);
} else {
	document.write('Not Opera Kernal');
}

使用的正则表达式是/Opera(?:.*Version)\/([\w.]+)/,表示包含"Opera",并且捕捉"Version/"之后的字符,直到下一个空格为止,作为版本号。

合并

将以上针对不同浏览器的代码串联起来,就可以实现jQuery.browser了。但jQuery中的实现更具有技巧性一些。下面是与jQuery中的实现比较接近的写法:

$ = function() {
    function uaMatch(ua) {
        ua = ua.toLowerCase();

        var match = rwebkit.exec(ua)
                    || ropera.exec(ua)
                    || rmsie.exec(ua)
                    || ua.indexOf("compatible") < 0 && rmozilla.exec(ua)
                    || [];

        return {
            browser : match[1] || "",
            version : match[2] || "0"
        };
    }

    var
    rwebkit = /(webkit)\/([\w.]+)/,
    ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
    rmsie = /(msie) ([\w.]+)/,
    rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,    
    browser = {},
    ua = window.navigator.userAgent,
    browserMatch = uaMatch(ua);

    if (browserMatch.browser) {
        browser[browserMatch.browser] = true;
        browser.version = browserMatch.version;
    }

    return { browser: browser }
}();

将这个JS文件命名为"jquery-browser.js",并在html中引用它:

<script type="text/javascript" src="jquery-browser.js"></script>
<script>
document.write('$.browser.webkit: ' + $.browser.webkit + '<br />');
document.write('$.browser.opera: ' + $.browser.opera + '<br />');
document.write('$.browser.msie: ' + $.browser.msie + '<br />');
document.write('$.browser.mozilla: ' + $.browser.mozilla + '<br />');
document.write('$.browser.version: ' + $.browser.version + '<br />');
</script>

效果与直接引用jquery.js是相同的。

让我们注意几个不同之处:

1.userAgent被转为小写字母进行匹配,避免了大小写的影响;

2.判断Mozilla时增加了ua.indexOf("compatible")<0,这是为了排除一些声称兼容Mozilla的浏览器的影响(比如IE8.0),一些搜索引擎的爬虫也经常声称兼容Mozilla;

3.检测Opera和Mozilla的正则表达式用"?"标明"rv"或"Version"是可有可无的,这可能是为了兼容不同的Opera和Mozilla内核浏览器(或较老的版本);

4.match捕捉的组有两个,第一个是浏览器内核名称,第二个是版本号,实现同时提取浏览器内核名称和版本号,减少了代码量。

以上就是jQuery.briwser的相对完整的实现了。主要的技巧是使用window.navigator.userAgent获取浏览器的描述字符串,以及通过正则表达式从该字符中提取信息。

相关推荐