网上对浏览器类型判断多是通过 User agent 字段。但是这种方法是不可靠的,因为 User agent 很容易被修改。
下面介绍的这种判断的方法符合“鸭子类型”的风格。
鸭子类型(英语:duck typing)在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
仅在确实需要时才使用这种浏览器检测方法,例如显示特定于浏览器的安装扩展说明。尽可能使用特征检测。
// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';
// Safari 3.0+ "[object HTMLElementConstructor]"
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;
// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;
// Chrome 1 - 79
var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
// Edge (based on chromium) detection
var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);
// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;
var output = 'Detecting browsers by ducktyping:<hr>';
output += 'isFirefox: ' + isFirefox + '<br>';
output += 'isChrome: ' + isChrome + '<br>';
output += 'isSafari: ' + isSafari + '<br>';
output += 'isOpera: ' + isOpera + '<br>';
output += 'isIE: ' + isIE + '<br>';
output += 'isEdge: ' + isEdge + '<br>';
output += 'isEdgeChromium: ' + isEdgeChromium + '<br>';
output += 'isBlink: ' + isBlink + '<br>';
document.body.innerHTML = output;
可靠性分析
以前的方法依赖渲染引擎的属性(-moz-box-sizing
and -webkit-transform
)来判断浏览器类型。这些前缀最终会被弃用。所以我转而使用更为健壮的方法——通过具体的浏览器的特性。
- Internet Explorer:JScript 的条件编译(直至 IE9)和
document.documentMode
。 - Edge:在 Trident 和 Edge 浏览器中,微软提供了
StyleMedia
构造函数 - Edge (基于 chromium 内核):在 user agent 的最后,包含了这样的值:
Edg/[version]
,如:(ex: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.16 Safari/537.36 Edg/80.0.361.9")
- Firefox:其用于安装附加组件的API:
InstallTrigger
- Chrome: 在全局对象
chrome
中,其属性之中有一个chrome.webstore
对象。但是在最近的版本中,chrome.webstore
将会被弃用。 - Safari:通过检查7.1版之后引入的
SafariRemoteNotification
,以涵盖3.0版及更高版本的 Safari。 - Opera:
window.opera
已经存在了很多年,但是将随着 Opera 将内核替换为 Blink + V8 而被弃用。Opera 15 中,user agent 字段更像 Chrome 的,但是额外的加入了 “OPR”。在这个本版中,
chrome
对象同样被定义,但是没有chrome.webstore
。自从 Opera 开始极力克隆 Chrome 后,我便使用 user agent 来判断它。!!window.opr && opr.addons
仍然可以用来识别 Opera 20 以上的版本! - Blink: 当 Google 将 Chrome 升级至 28 版时,
CSS.supports()
被引入 Blink。理所当然的,同样的 Blink 也会被 Opera 使用。
测试成功的浏览器
- Firefox 0.8 - 61
- Chrome 1.0 - 71
- Opera 8.0 - 34
- Safari 3.0 - 10
- IE 6 - 11
- Edge - 20-42
- Edge Dev - 80.0.361.9
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。