浏览器的检测这是一个谈烂的话题,这次拿出来说,也没有其他特别的目的,现在主流的类库都已经完好的支持了所有主流的浏览器嗅探。
但是对于国内用户来说,还有很多用户正在使用maxthon,360,sogou,TT等这样的浏览器。
我们知道判断浏览器有两种方法,一种是直接根据UA来检测,一种是根据浏览器的特性来判断。
关于 navigator.userAgent
IE6-IE8没有啥说的
UA 只需要匹配 MSIE + 版本号就可以了
从IE7 到IE8的UA
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; Tablet PC 2.0)
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; InfoPath.2; Tablet PC 2.0)
对于非IE来说
UA分别是
FF3.6 Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16c
chrome Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)
AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151
Safari/534.16
safari Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13
对于国产浏览器来说
UA 则是
TT Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1 TencentTraveler 4.0; .NET CLR 2.0.50727)
world Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1 TencentTraveler 4.0; .NET CLR 2.0.50727; TheWorld)
360 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1 TencentTraveler 4.0; .NET CLR 2.0.50727; 360SE)
maxthon Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/531.0 (KHTML, like Gecko) Chrome/5.0.195.0 Safari/531.0
sougo Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.33 Safari/534.3 SE 2.X MetaSr 1.0
关于UA的总结:
通过UA来判断IE版本号,只需要匹配出MSIE + 版本号就可以了,IE9也是如此
通过UA来判断FF、Chrome、Safari的话,FF只需要判断gecko 或是 firefox,chrome则在UA含有 Chrome 和 Safari,所以先判断chrome,再判断是safari可以区分开chrome 和 safari
关于国产浏览器
TT 在打开的时候会临时篡改UA,发现打开TT后,所有IE核心的浏览器的UA里都含有TencentTravler了
world 和 360 都是在UA的后面加上了自己的标识
maxthon和sougo都是双核浏览器了,用的是 webkit 和 IE 的trident
maxthon 3的UA不会包含自己的标识,但是可以通过window.external.max_version来判断
最后得出一下代码:
if(/applewebkit\/([\d.]*)/.test(ua)){
core = 'webkit';
}else if(/presto\/([\d.]*)/.test(ua)){
core = 'presto';
}else if(/msie\s([^;]*)/.test(ua)){
core = 'trident';
}else if(/gecko/.test(ua)){
core = 'gecko';
}
if(/world/.test(ua)){
extra = 'world';
}else if(/360se/.test(ua)){
extra = '360';
}else if((/maxthon/.test(ua)) || typeof external.max_version == 'number'){
extra = 'maxthon';
}else if(/tencenttraveler\s([\d.]*)/.test(ua)){
extra = 'tt';
}else if(/se\s([\d.]*)/.test(ua)){
extra = 'sogou';
}
return {
'CORE':core,
'EXTRA':(extra?extra:false),
'IE': /msie/.test(ua),
'IE5': /msie 5 /.test(ua),
'IE55': /msie 5.5/.test(ua),
'IE6': /msie 6/.test(ua),
'IE7': /msie 7/.test(ua),
'IE8': /msie 8/.test(ua),
'IE9': /msie 9/.test(ua),
'SAFARI': !/chrome\/([\d.]*)/.test(ua) && /\/([\d.]*) safari/.test(ua),
'CHROME': /chrome\/([\d.]*)/.test(ua)
}
说完了UA,来说说特性检测吧,所有的浏览器对js的解释都不太一样,就导致了有些浏览器往往有其自己的特殊的方法,我们在写代码实现的时候,对于浏览器的检测比较推荐的做法就是特性检测而非UA检测,因为UA是可以被篡改的。
我们都知道在IE浏览器下,是没有直接创建XMLHttpRequest的方法,必须要通过ActiveXObject来创建,所以判断的时候直接判断是否能够创建XMLHttpRequest来使用ajax请求,还有event对象的target和srcElement等等,这些都是经典的例子。
然而也有很多不那么经典的例子,比如CSS里的 fixed ,还有盒模型的解释等等。比较推荐的做法是在页面初始化的时候计算他的盒模型和fixed解释模式,然后记下,之后的判断基于初始化时计算的结构,而不是浏览器的版本。
关于判断核心
另外可以通过判断document.style里的属性来判断浏览器内核比如
docElement = document.documentElement;
isWebkit = ('webkitAppearance' in docElement.style)
isGecko = ('MozAppearance' in docElement.style)