Angularjsは初めてです。 angularjsでuserAgentを検出するにはどうすればよいですか。コントローラでそれを使用することは可能ですか?以下のようなものを試してみましたが、運はありません!
var browserVersion = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
IE9を具体的に検出する必要があります!
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);
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
}
}
条件付きコメントを使用する必要があります
<!--[if IE 9]>
<script type="text/javascript">
window.isIE9 = true;
</script>
<![endif]-->
その後、コントローラーで$ window.isIE9を確認できます。
なぜAngular内にあると指定するのか分かりません。 JavaScriptを使用して簡単に実現できます。 navigator
オブジェクトを見てください。
コンソールを開いて、navigator
を調べてください。特に探しているのは.userAgent
または.appVersion
です。
IE9はインストールしていませんが、次のコードを試すことができます
//Detect if IE 9
if(navigator.appVersion.indexOf("MSIE 9.")!=-1)
「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);
}]);
したがって、コンテンツを含むファイルを作成することで、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");
}
}
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;
}
};
});
ブラウザのようなエンティティを簡単に検出できるライブラリng-device-detectorがあります。
このライブラリの使用方法を説明するチュートリアルがあります。 AngularJSでOS、ブラウザ、およびデバイスを検出
Re-tree.jsおよびng-device-detector.jsスクリプトをHTMLに追加する必要があります
モジュールに依存関係として「ng.deviceDetector」を挿入します。
次に、ライブラリが提供する「deviceDetector」サービスを、データが必要な場所のコントローラーまたは工場に注入します。
「deviceDetector」には、ブラウザ、OS、およびデバイスに関するすべてのデータが含まれています。
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.
}
通常、ブラウザのスニッフィングは避ける必要があり、機能の検出ははるかに優れていますが、場合によっては行う必要があります。たとえば、私の場合、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
検出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
}