就像 Eliran Malka 所问的那样,为什么需要检查 IE 9?
检测浏览器的品牌和版本通常很糟糕。这通常意味着如果您需要 JavaScript 来检测特定版本的浏览器,则代码存在更大的问题。
确实存在某些功能不起作用的情况,例如 IE 8 或 9 不支持 WebSockets。这应该通过检查 WebSocket 支持来解决,如果没有原生支持,则应用 polyfill。
这应该通过像 Modernizr 这样的库来完成。
话虽如此,您可以轻松创建返回浏览器的服务。在某些情况下,浏览器中存在功能但实现已过时或损坏。 Modernizr 不适用于这些情况。
app.service('browser', ['$window', function($window) {
return function() {
var userAgent = $window.navigator.userAgent;
var browsers = {chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i};
for(var key in browsers) {
if (browsers[key].test(userAgent)) {
return key;
}
};
return 'unknown';
}
}]);
修正了错字浏览器
注意:这只是一个示例,说明如何在 Angular 中创建将嗅探 userAgent 字符串的服务。这只是一个代码示例,预计不会在生产环境中工作并报告所有情况下的所有浏览器。
更新
最好使用像https://github.com/ded/bowser 或https://github.com/darcyclarke/Detect.js 这样的第三方库。这些库分别在名为 bowser 或 detect 的 window 上放置一个对象。
然后您可以像这样向Angular IoC Container 公开它:
angular.module('yourModule').value('bowser', bowser);
或者
detectFactory.$inject = ['$window'];
function detectFactory($window) {
return detect.parse($window.navigator.userAgent);
}
angular.module('yourModule').factory('detect', detectFactory);
然后,您会以通常的方式注入其中一种,并使用 lib 提供的 API。如果您选择使用另一个使用构造函数方法的库,您将创建一个实例化它的工厂:
function someLibFactory() {
return new SomeLib();
}
angular.module('yourModule').factory('someLib', someLibFactory);
然后,您可以以正常方式将其注入您的控制器和服务中。
如果您要注入的库与您的要求不完全匹配,您可能需要使用Adapter Pattern,您可以在其中使用您需要的确切方法创建一个类/构造函数。
在这个例子中,我们只需要测试 IE 9,我们将使用上面的 bowser 库。
BrowserAdapter.$inject = ['bowser']; // bring in lib
function BrowserAdapter(bowser) {
this.bowser = bowser;
}
BrowserAdapter.prototype.isIe9 = function() {
return this.bowser.msie && this.browser.version == 9;
}
angular.module('yourModule').service('browserAdapter', BrowserAdapter);
现在在控制器或服务中,您可以注入 browserAdapter 并执行 if (browserAdapter.isIe9) { // do something }
如果稍后您想使用检测而不是 bowser,则代码中的更改将被隔离到 BrowserAdapter。
更新
实际上,这些值永远不会改变。如果您在 IE 9 中加载页面,它将永远不会成为 Chrome 44。因此,不要将 BrowserAdapter 注册为服务,只需将结果放入 value 或 constant。
angular.module('app').value('isIe9', broswerAdapter.isIe9);