Как определить браузер с помощью angular?
Я новичок в angular. Как определить userAgent в angular. Можно ли использовать это в контроллере? Пробовал что-то вроде ниже, но не повезло!
var browserVersion = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
Мне нужно специально определить IE9!
Ответы
Ответ 1
Как и Элиран Малка спросил, почему вам нужно проверить 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
Примечание.. Это всего лишь пример того, как создать службу в angular, которая будет обманывать строку userAgent. Это всего лишь пример кода, который, как ожидается, не будет работать в производстве, и сообщит обо всех браузерах во всех ситуациях.
UPDATE
Вероятно, лучше использовать стороннюю библиотеку, например https://github.com/ded/bowser или https://github.com/darcyclarke/Detect.js. Эти libs помещают объект в window
named bowser или обнаруживают соответственно.
Затем вы можете вывести это значение в 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);
Затем вы добавите один из них обычным способом и используйте API, предоставленный lib. Если вы решите использовать другую библиотеку, которая вместо этого использует метод конструктора, вы создадите factory, который ее создаст:
function someLibFactory() {
return new SomeLib();
}
angular.module('yourModule').factory('someLib', someLibFactory);
Затем вы вводите это в свои контроллеры и службы обычным способом.
Если библиотека, которую вы вводите, не соответствует вашим требованиям, вы можете использовать Adapter Pattern
, где вы создаете класс/конструктор с точными методами, которые вам нужны.
В этом примере нам просто нужно протестировать IE 9, и мы будем использовать выше bowser
lib.
BroswerAdapter.$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.
UPDATE
В действительности эти ценности никогда не меняются. Если вы загружаете страницу в IE 9, она никогда не станет Chrome 44. Поэтому вместо регистрации BrowserAdapter в качестве службы просто поместите результат в value
или constant
.
angular.module('app').value('isIe9', broswerAdapter.isIe9);
Ответ 2
Библиотека Angular использует document.documentMode для идентификации IE. Он содержит основной номер версии для IE или NaN/ undefined, если User Agent не является IE.
/**
* 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 (angular wrapper для 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
}
}
Ответ 3
вы должны использовать условные комментарии
<!--[if IE 9]>
<script type="text/javascript">
window.isIE9 = true;
</script>
<![endif]-->
Затем вы можете проверить $window.isIE9 на своих контроллерах.
Ответ 4
Не знаете, почему вы указываете, что он должен находиться в пределах Angular. Это легко достигается с помощью JavaScript. Посмотрите на navigator
объект.
Просто откройте консоль и проверьте navigator
. Кажется, что вы ищете именно .userAgent
или .appVersion
.
У меня нет IE9, но вы можете попробовать следующий код
//Detect if IE 9
if(navigator.appVersion.indexOf("MSIE 9.")!=-1)
Ответ 5
Вы можете легко использовать модуль "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);
}]);
Ответ 6
Итак, вы можете объявить больше утилит для 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
Я модифицировал вышеупомянутый метод, который был близок к тому, что я хотел для angular, и превратил его в сервис:-). Я включил 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;
}
};
});
Ответ 8
Существует библиотека ng-device-detector, которая позволяет обнаруживать объекты, такие как браузер, os easy.
Вот учебник, в котором объясняется, как использовать эту библиотеку. Обнаружение ОС, браузера и устройства в AngularJS
ngDeviceDetector
Вам нужно добавить скрипты re-tree.js и ng-device-detector.js в свой html
Ввести "ng.deviceDetector" как зависимость в вашем модуле.
Затем добавьте услугу "deviceDetector", предоставляемую библиотекой, в ваш контроллер или factory, где вам нужны данные.
"deviceDetector" содержит все данные о браузере, os и устройстве.
Ответ 9
Почему бы не использовать document.documentMode
только в IE:
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.
}
Ответ 10
Обход браузера вообще следует избегать, функция обнаружения намного лучше, но иногда вам приходится это делать. Например, в моем случае Windows 8 Tablets перекрывают окно браузера с помощью мягкой клавиатуры; Смешно я знаю, но иногда вам приходится иметь дело с реальностью.
Таким образом, вы бы измерили "navigator.userAgent" как с обычным JavaScript (пожалуйста, не погружайтесь в привычку рассматривать Angular как нечто отличное от JavaScript, используйте простой JavaScript, если это возможно, это приведет к меньшему будущему рефакторингу).
Однако для тестирования вы хотите использовать инъецированные объекты, а не глобальные. Поскольку "$ location" не содержит userAgent, простой трюк заключается в использовании "$ window.location.userAgent". Теперь вы можете писать тесты, которые вводят оконную заглушку $с любым пользователем, который вы не хотите имитировать.
Ответ 11
Обнаружение 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
}