如何使用angularjs检测浏览器?

seU*_*ser 63 angularjs angular-ui angularjs-directive angularjs-scope

我是angularjs的新手.如何在angularjs中检测userAgent.是否可以在控制器中使用它?试过类似下面的东西,但没有运气!

  var browserVersion = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
Run Code Online (Sandbox Code Playgroud)

我需要专门检测IE9!

Mar*_*tin 67

就像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';
    }

}]);
Run Code Online (Sandbox Code Playgroud)

修正了错字broswers

注意:这只是如何以角度创建服务以嗅探userAgent字符串的示例.这只是一个代码示例,预计不会在生产中工作并在所有情况下报告所有浏览器.

UPDATE

最好使用第三方库,如https://github.com/ded/bowserhttps://github.com/darcyclarke/Detect.js.这些库分别将对象放置在window命名的bowser或detect.

然后你可以将它暴露在Angular IoC Container这样的:

angular.module('yourModule').value('bowser', bowser);
Run Code Online (Sandbox Code Playgroud)

要么

detectFactory.$inject = ['$window'];
function detectFactory($window) {
    return detect.parse($window.navigator.userAgent);
} 
angular.module('yourModule').factory('detect', detectFactory);
Run Code Online (Sandbox Code Playgroud)

然后,您将以常规方式注入其中一个,并使用lib提供的API.如果您选择使用另一个使用构造函数方法的库,您将创建一个实例化它的工厂:

function someLibFactory() {
    return new SomeLib();
}
angular.module('yourModule').factory('someLib', someLibFactory);
Run Code Online (Sandbox Code Playgroud)

然后,您将以正常方式将其注入您的控制器和服务中.

如果您注入的库与您的要求不完全匹配,您可能希望使用所需Adapter Pattern的确切方法创建类/构造函数的位置.

在这个例子中,我们只需要测试IE 9,我们将使用bowser上面的lib.

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);
Run Code Online (Sandbox Code Playgroud)

现在在控制器或服务中,您可以注入browserAdapter并执行操作if (browserAdapter.isIe9) { // do something }

如果稍后您想使用detect而不是bowser,则代码中的更改将被隔离到BrowserAdapter.

UPDATE

实际上,这些价值观永远不变.如果您在IE 9中加载页面,它将永远不会成为Chrome 44.因此,不要将BrowserAdapter注册为服务,只需将结果放入valueconstant.

angular.module('app').value('isIe9', broswerAdapter.isIe9);
Run Code Online (Sandbox Code Playgroud)

  • `forEach`中的拼写错误:_broswers_,替换为**浏览器** (2认同)
  • 最新版本的 Chrome 报告:“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36”。因此,根据 forEach 语句检索键的顺序,它可以返回不同的结果。 (2认同)
  • “检测浏览器的品牌和版本通常是一种难闻的气味。” 不,当您认为检测浏览器版本100的99的目的是针对可疑的Internet Explorer时,不是这样。在我从事Web开发的6年中,由于Internet Explorer的缘故,我只需要此功能,原因是IE自1995年以来一直假装为Mozilla,这向您显示这是Microsoft的错,而不是Web开发人员的错。 (2认同)

Boh*_*ets 26

Angular库使用document.documentMode来识别IE.它包含IE的主要版本号,如果用户代理不是IE,则为NaN/undefined.

/**
* documentMode is an IE-only property
* http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
*/
var msie = document.documentMode;
Run Code Online (Sandbox Code Playgroud)

https://github.com/angular/angular.js/blob/v1.5.0/src/Angular.js#L167-L171

$ document的示例(window.document的角度包装器)

// var msie = document.documentMode;
var msie = $document[0].documentMode;
// if is IE (documentMode contains IE version)
if (msie) {
  // IE logic here

  if (msie === 9) {
    // IE 9 logic here

  }
}
Run Code Online (Sandbox Code Playgroud)

  • 有几次我遇到了大量复杂的答案,在window.navigator等上进行正则表达式测试.当它只是我们希望失败的IE时,这似乎是一种奇特的最佳方式. (5认同)

Mic*_*ael 15

你应该使用条件评论

<!--[if IE 9]>
<script type="text/javascript">
    window.isIE9 = true;
</script>
<![endif]-->
Run Code Online (Sandbox Code Playgroud)

然后,您可以在控制器中检查$ window.isIE9.

  • OP说:我需要专门检测IE9! (16认同)
  • 这些不再适用于IE10和IE11. (4认同)

Eni*_*aRM 13

不确定为什么你指定它必须在Angular中.它可以通过JavaScript轻松完成.看看navigator对象.

打开你的控制台并检查navigator.看起来你特别想要的是.userAgent.appVersion.

我没有安装IE9,但您可以尝试以下代码

//Detect if IE 9
if(navigator.appVersion.indexOf("MSIE 9.")!=-1)
Run Code Online (Sandbox Code Playgroud)


Use*_*NeD 12

您可以轻松使用"ng-device-detector"模块.

https://github.com/srfrnk/ng-device-detector

var app = angular.module('myapp', ["ng.deviceDetector"]);
app.controller('DeviceCtrl', ["$scope","deviceDetector",function($scope,deviceDetector) {
      console.log("browser: ", deviceDetector.browser);
      console.log("browser version: ", deviceDetector.browser_version);
      console.log("device: ", deviceDetector.device);
}]);
Run Code Online (Sandbox Code Playgroud)


hai*_*zpt 7

因此,您可以通过带内容的创建文件为角度声明更多实用程序(我遵循RGraph库)

(function(window, angular, undefined) {'use strict';
    var agl = angular || {};
    var ua  = navigator.userAgent;

    agl.ISFF     = ua.indexOf('Firefox') != -1;
    agl.ISOPERA  = ua.indexOf('Opera') != -1;
    agl.ISCHROME = ua.indexOf('Chrome') != -1;
    agl.ISSAFARI = ua.indexOf('Safari') != -1 && !agl.ISCHROME;
    agl.ISWEBKIT = ua.indexOf('WebKit') != -1;

    agl.ISIE   = ua.indexOf('Trident') > 0 || navigator.userAgent.indexOf('MSIE') > 0;
    agl.ISIE6  = ua.indexOf('MSIE 6') > 0;
    agl.ISIE7  = ua.indexOf('MSIE 7') > 0;
    agl.ISIE8  = ua.indexOf('MSIE 8') > 0;
    agl.ISIE9  = ua.indexOf('MSIE 9') > 0;
    agl.ISIE10 = ua.indexOf('MSIE 10') > 0;
    agl.ISOLD  = agl.ISIE6 || agl.ISIE7 || agl.ISIE8; // MUST be here

    agl.ISIE11UP = ua.indexOf('MSIE') == -1 && ua.indexOf('Trident') > 0;
    agl.ISIE10UP = agl.ISIE10 || agl.ISIE11UP;
    agl.ISIE9UP  = agl.ISIE9 || agl.ISIE10UP;

})(window, window.angular);
Run Code Online (Sandbox Code Playgroud)

之后,在你的功能中使用可以使用它

function SampleController($scope){
    $scope.click = function () {
        if(angular.ISCHROME) {
        alert("is chrome");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Monkey patching angular is considered a bad practice. (5认同)
  • 是的,马丁,我们可以改用另一个变量window.angular。不需要window.angular (2认同)