我觉得,无论userAgent多复杂多麻烦,我还是更相信它。至少,世界上没有两个相同的userAgent。
另外,作为一个痴迷于js痴迷于前端的人,我无视360浏览器、遨游、世界之窗、搜狗等诸多产品,我觉得我一直坚持兼容IE6就已经很蛋疼了。

那么,首先,我们搜集一下各个主流浏览器当前版本的userAgent样本,以便做进一步的分析整理。

Chrome 9
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Chrome/9.0.570.0 Safari/534.11

Opera 11
Opera/9.80 (Windows NT 6.1; U; Edition IBIS; zh-cn) Presto/2.7.62 Version/11.00

Safari 5
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4

Firefox 3
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13

IE 8
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; 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; InfoPath.2)

IE 6 (ieTester)
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.1; WOW64; 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; InfoPath.2)

请注意黑体字。这些信息足够明确了吗:浏览器名称+版本号,中间间隔是空格或者斜杠。

唯一有点搞笑的是,Chrome的信息里带着Safari的字样,而且版本还挺新的。不过下一步我将使用正则来提取信息,并且不做全局的匹配,所以由于Chrome的Safari字样在Chrome字样之后,也不会影响提取结果。下面是这段特别直白的正则:

var reg = ua.match(/(IE|Firefox|Opera|Chrome|Safari)[\s\/]+([\d\.]+)([\w\W]*Safari\/[\d\.]+)?/i);

这段正则里我还是捕获了一下Chrome中的Safari。后面基本用不到这一段。

为了让提取的信息更好用,我将浏览器信息分为三部分:浏览器名称、版本(小版本号)和浏览器的is属性判断。

根据上面那段正则,很容易得到浏览器名称:

w.browser = new String(reg[1]);

我用了字符串对象,为的是继续添加子属性。下面添加版本号:

w.browser.version = !!reg[2] ? reg[2].toString() : '-1';
w.browser.ver = parseInt(w.browser.version);

版本号version是完整版本,ver是大版本号。有了上面三个值,下面实现is属性判断:

w.browser['is' + w.browser] = w.browser['is' + w.browser + w.browser.ver] = w.browser['is' + w.browser + w.browser.version] = true;

这里使用js文字标签定义属性。看出来实现了什么?

比如IE8浏览器:window.isIE,window.isIE8,window['isIE8.0']皆可判断。

奉上muselite类库的浏览器版本判断完整代码:

	/*
	判断浏览器版本
	*/
	(function(w, ua){
		var reg = ua.match(/(IE|Firefox|Opera|Chrome|Safari)[\s\/]+([\d\.]+)([\w\W]*Safari\/[\d\.]+)?/i);
		if(!!reg) {
			w.browser = new String(reg[1]);
			w.browser.version = !!reg[2] ? reg[2].toString() : '-1';
			w.browser.ver = parseInt(w.browser.version);
			w.browser['is' + w.browser] = w.browser['is' + w.browser + w.browser.ver] = w.browser['is' + w.browser + w.browser.version] = true;
		} else w.browser = 'Unknown';
		reg = null;
	})(window, window.navigator.userAgent);

还没完呢。

下面是语言的获取。语言设置很重要吗?不重要吗?很重要吗?不重要吗?……

先说获取的事:如果浏览器没有nav.userLanguage || nav.systemLanguage || nav.browserLanguage三个值,那么只能继续从ua里面提取。其实也很简单,就是那个xx-xx的那一段。

贴代码,没啥可说的了:

/*
	获取语言设置
	*/
	(function(w, nav){
		if(!(w.lang = nav.userLanguage || nav.systemLanguage || nav.browserLanguage)){
			w.lang = (!!nav.userAgent.match(/;\s*(\w+\-\w+)[;\)]/) ? RegExp['$1'] : 'zh-cn').toLowerCase();
		}
	})(window, window.navigator);

然后,告诉你一个yd的用法。

indow.tips = {
    'zh-cn' : { Close : '关闭', Open : '打开', Restore : '恢复', Minimize : '最小化', Maximize : '最大化', Cancel : '取消' },
    'en-us' : { ... }
}[window.lang]

alert(window.tips.Close);