正如 YAHOO.env.ua 字面所指(ua 就是 user-agent 的意思),这篇文章主要分析 YUI 如何检测浏览器的类型与版本。有关 YAHOO.en.ua 的文档 在这里说明 。
目前为止,检测浏览器与版本主要有两大主流的做法。其一,就是分析浏览器提供的 user-agent 字符串;其二,就是根据其功能判别。YUI 使用第一种判断方式,也就是分析 user-agent 字符串。
下面是 YUI 相应的代码实现,经过本人精简以后并加了点注释,这段程序在 %BUILD%/yahoo/yahoo.js 中。
YAHOO.env.ua = function() {
var o={ie:0, opera:0, gecko:0, webkit:0, mobile: null};
var ua=navigator.userAgent, m;
// 是否为基于 KHTML 引擎的浏览器,比如 Konqueror 。
if ((/KHTML/).test(ua)) {
o.webkit=1;
}
// 检测 Apple 系列的浏览器,包括移动版本
m=ua.match(/AppleWebKit\/([^\s]*)/);
if (m&&m[1]) {
o.webkit=parseFloat(m[1]);
// YUI 是我见过的唯一一个检测移动浏览器的框架 :^)
if (/ Mobile\//.test(ua)) {
o.mobile = "Apple"; // iPhone or iPod Touch
} else {
m=ua.match(/NokiaN[^\/]*/);
if (m) {
o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
}
}
}
if (!o.webkit) { // 检测其他浏览器
// 检测 Opera
m=ua.match(/Opera[\s\/]([^\s]*)/);
if (m&&m[1]) {
o.opera=parseFloat(m[1]);
// 是否为 Opera 移动版本
m=ua.match(/Opera Mini[^;]*/);
if (m) {
o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
}
} else {
// 检测 IE 和 Mozilla
m=ua.match(/MSIE\s([^;]*)/);
if (m&&m[1]) {
o.ie=parseFloat(m[1]);
} else {
m=ua.match(/Gecko\/([^\s]*)/);
if (m) {
o.gecko=1;
m=ua.match(/rv:([^\s\)]*)/);
if (m&&m[1]) {
o.gecko=parseFloat(m[1]);
}
}
}
}
}
return o;
}();
根据代码的流程,我们可以很容易理解 YUI 判断浏览器的逻辑。而我在之前也分析过 jQuery 在这方面是如何做的 ,可以对比参照下。
从代码量上考虑,jQuery 的代码是非常的精简的,而 YUI 「看起来」更像是我们平常一般的写法:保守、但是有效。而我个人更倾向于 jQuery 的写法,当然 YUI 这这样的判断流程自然也是有它的道理的。
请允许我多事一下,下面是本人根据 jQuery 的代码「重写」 YUI 的 YAHOO.env.ua ,让大家见笑了。
YAHOO.env.ua = function() { var ua = navigator.userAgent.toLowerCase(); var version = (ua.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1]; return { webkit: /webkit/.test(ua) ? version : 0, opera: /opera/.test(ua) ? version : 0, ie: /msie/.test(ua) && !/opera/.test(ua) ? version : 0, gecko: /mozilla/.test(ua)&&!/(compatible|webkit)/.test(ua) ? version : 0, mobile: / mobile\//.test(ua) || ua.match(/nokian[^\/]*/) || ua.match(/opera mini[^;]*/) ? version : 0 }; }();
完了,彻底转型了.js疯人.
@wiLdGoose 兄台别见怪,我只不过将我的笔记整理了下一并发了上来。
不错的东西.只有win mobi才能用吧?
不错,分析框架