web-dev-qa-db-ja.com

angularjsを使用してブラウザを検出する方法は?

Angularjsは初めてです。 angularjsでuserAgentを検出するにはどうすればよいですか。コントローラでそれを使用することは可能ですか?以下のようなものを試してみましたが、運はありません!

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

IE9を具体的に検出する必要があります!

61
seUser

Eliran Malkaが尋ねたように、なぜIE 9をチェックする必要があるのですか?

ブラウザのメーカーとバージョンを検出することは、一般に悪臭です。これは一般的に、ブラウザの特定のバージョンを検出するためにJavaScriptが必要な場合、コードに大きな問題があることを意味します。

WebSocketがIE 8または9でサポートされていないなど、機能が機能しない場合があります。これは、WebSocketサポートを確認し、ネイティブがない場合はポリフィルを適用することで解決する必要がありますサポート。

これは、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';
    }

}]);

固定されたタイプミスブラザー

注:これは、userAgent文字列をスニッフィングするangularでサービスを作成する方法の単なる例です。これは単なるコード例であり、本番環境では動作せず、すべての状況ですべてのブラウザーを報告することは想定されていません。

UPDATE

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 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 }を実行できます

後でbowserの代わりにdetectを使用する場合、コードの変更はBrowserAdapterに分離されます。

UPDATE

実際には、これらの値は決して変わりません。 IE 9にページをロードすると、Chrome 44にはなりません。したがって、BrowserAdapterをサービスとして登録する代わりに、結果をvalueまたはconstantに入れるだけです。

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

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

  }
}
22
Bohdan Lyzanets

条件付きコメントを使用する必要があります

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

その後、コントローラーで$ window.isIE9を確認できます。

15
Michael

なぜAngular内にあると指定するのか分かりません。 JavaScriptを使用して簡単に実現できます。 navigator オブジェクトを見てください。

コンソールを開いて、navigatorを調べてください。特に探しているのは.userAgentまたは.appVersionです。

IE9はインストールしていませんが、次のコードを試すことができます

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

「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);
}]);
12
UserNeD

したがって、コンテンツを含むファイルを作成することで、angularのユーティリティをさらに宣言できます(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");
    }
}
7
haizpt

angularに必要なものに近い上記の手法を変更し、サービスに変換しました:-)。私は私のangularjsアプリでいくつかの問題を抱えていたのでIE9を含めましたが、私がやっていることになる可能性がありますので、それを取り出してください。

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;
  }
};

});
4
mike gold

ブラウザのようなエンティティを簡単に検出できるライブラリng-device-detectorがあります。

このライブラリの使用方法を説明するチュートリアルがあります。 AngularJSでOS、ブラウザ、およびデバイスを検出

ngDeviceDetector

Re-tree.jsおよびng-device-detector.jsスクリプトをHTMLに追加する必要があります

モジュールに依存関係として「ng.deviceDetector」を挿入します。

次に、ライブラリが提供する「deviceDetector」サービスを、データが必要な場所のコントローラーまたは工場に注入します。

「deviceDetector」には、ブラウザ、OS、およびデバイスに関するすべてのデータが含まれています。

3
rahil471

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.
}
1

通常、ブラウザのスニッフィングは避ける必要があり、機能の検出ははるかに優れていますが、場合によっては行う必要があります。たとえば、私の場合、Windows 8 Tabletsはブラウザーウィンドウとソフトキーボードを重ねています。ばかげたことは知っていますが、時には現実に対処する必要があります。

したがって、通常のJavaScriptと同様に 'navigator.userAgent'を測定します(AngularをJavaScriptとは異なるものとして扱う習慣に陥らないでください。可能な場合はプレーンなJavaScriptを使用して、リファクタリングを減らしてください) 。

ただし、テストでは、グローバルオブジェクトではなく、挿入されたオブジェクトを使用する必要があります。 「$ location」にはuserAgentが含まれていないため、単純なトリックは「$ window.location.userAgent」を使用することです。シミュレートしたくないuserAgentを使用して$ windowスタブを挿入するテストを作成できるようになりました。

私は何年も使っていませんが、Modernizrは機能をチェックするための優れたソースコードです。 https://github.com/Modernizr/Modernizr/issues/878#issuecomment-41448059

1
Henrik Vendelbo

検出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
}
0
Alex Golovin