如何使用angularjs检测浏览器?

时间:2014-04-08 20:29:57

标签: angularjs angularjs-directive angularjs-scope angular-ui

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

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

我需要专门检测IE9!

11 个答案:

答案 0 :(得分: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';
    }

}]);

修正错字broswers

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

<强>更新

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

然后,您可以将其公开给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 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);

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

如果以后想要使用detect而不是bowser,代码中的更改将被隔离到BrowserAdapter。

<强>更新

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

angular.module('app').value('isIe9', broswerAdapter.isIe9);

答案 1 :(得分:22)

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;

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

  }
}

答案 2 :(得分:15)

你应该使用条件评论

<!--[if IE 9]>
<script type="text/javascript">
    window.isIE9 = true;
</script>
<![endif]-->

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

答案 3 :(得分:12)

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

只需打开控制台并检查navigator即可。您专门寻找的内容似乎是.userAgent.appVersion

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

//Detect if IE 9
if(navigator.appVersion.indexOf("MSIE 9.")!=-1)

答案 4 :(得分: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);
}]);

答案 5 :(得分: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);

之后,在你的函数中使用可以像

一样使用它
function SampleController($scope){
    $scope.click = function () {
        if(angular.ISCHROME) {
        alert("is chrome");
    }
}

答案 6 :(得分:4)

我修改了上面的技术,它接近我想要的角度并将其变成服务:-)。我包括了ie9,因为我在我的angularjs应用程序中遇到了一些问题,但可能是我正在做的事情,所以请随意把它拿出来。

angular.module('myModule').service('browserDetectionService', function() {

 return {
isCompatible: function () {

  var browserInfo = navigator.userAgent;
  var browserFlags =  {};

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

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

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

  return !browserFlags.ISOLD;
  }
};

});

答案 7 :(得分:3)

有一个库ng-device-detector,可以像浏览器一样检测实体,操作系统很容易。

以下是解释如何使用此库的教程。 Detect OS, browser and device in AngularJS

ngDeviceDetector

您需要将re-tree.js和ng-device-detector.js脚本添加到您的html中

将“ng.deviceDetector”作为模块中的依赖项注入。

然后将库提供的“deviceDetector”服务注入您想要数据的控制器或工厂。

“deviceDetector”包含有关浏览器,操作系统和设备的所有数据。

答案 8 :(得分:1)

为什么不使用仅在IE下提供的document.documentMode

var doc = $window.document;
if (!!doc.documentMode)
{
  if (doc.documentMode === 10)
  {
    doc.documentElement.className += ' isIE isIE10';
  }
  else if (doc.documentMode === 11)
  {
    doc.documentElement.className += ' isIE isIE11';
  }
  // etc.
}

答案 9 :(得分:1)

通常应避免浏览器嗅探,功能检测要好得多,但有时您必须这样做。例如,在我的情况下,Windows 8平板电脑与软键盘重叠浏览器窗口;荒谬我知道,但有时你必须处理现实。

所以你要测量一下navigator.userAgent&#39;和普通的JavaScript一样(请不要习惯将Angular视为与JavaScript不同的东西,如果可能的话,使用普通的JavaScript会导致未来的重构更少)。

但是,对于测试,您希望使用注入的对象而不是全局的对象。由于&#39; $ location&#39;不包含userAgent,简单的技巧是使用&#39; $ window.location.userAgent&#39;。您现在可以编写测试,使用您无法模拟的任何userAgent注入$ window存根。

我还没有使用它多年,但Modernizr是检查功能的良好代码来源。 https://github.com/Modernizr/Modernizr/issues/878#issuecomment-41448059

答案 10 :(得分:0)

检测ie9 +

var userAgent, ieReg, ie;
  userAgent = $window.navigator.userAgent;
  ieReg = /msie|Trident.*rv[ :]*11\./gi;
  ie = ieReg.test(userAgent);

if (ie) {
   // js for ie9,10 and 11
}