Обнаружение Javascript IE, почему бы не использовать простые условные комментарии? - PullRequest
47 голосов
/ 13 ноября 2010

Для обнаружения IE большинство библиотек Javascript выполняют всевозможные трюки.

  • jQuery, кажется, добавляет временный объект в DOM ваших страниц для обнаружения некоторых функций,
  • YUI2 выполняет регулярное выражение для пользовательского агента в своем YAHOO.env.ua = function() (файл yahoo.js)

После прочтения этого ответа мне пришло в голову, что это правда, чтобы просто определить IE в Javascript, мы могли бы просто добавить на наши страницы:

<!--[if IE]><script type="text/javascript">window['isIE'] = true;</script><![endif]-->

<script type="text/javascript" src="all-your-other-scripts-here.js"></script>

Теперь переменная window.isIE устанавливается для всего нашего кода Javascript, просто выполнив:

if(window.isIE)
   ...

Помимо того, что это может привести к боли, потому что это нужно добавить на всех страницах, Есть ли какие-либо проблемы / соображения, о которых я мог бы не знать?


К вашему сведению: я знаю, что лучше использовать обнаружение объектов, а не обнаружение в браузере , но в некоторых случаях вам все равно придется использовать обнаружение в браузере.

Ответы [ 15 ]

59 голосов
/ 19 ноября 2010

Джеймс Падолси поместил небольшой фрагмент на GitHub , который я процитирую здесь:

// ----------------------------------------------------------
// A short snippet for detecting versions of IE in JavaScript
// without resorting to user-agent sniffing
// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
// ie === undefined
// If you're in IE (>=5) then you can determine which version:
// ie === 7; // IE7
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------

// UPDATE: Now using Live NodeList idea from @jdalton

var ie = (function(){

    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;

}());

Конечно, все кредиты должны идти Джеймсу, я всего лишь посланник (но, пожалуйста, пристрелите посланника, если мое действие копирования-вставки было ошибочным).

Также посмотрите на вилки, которые были созданы. Пол Ирриш объяснил внутреннюю работу в комментарии .

40 голосов
/ 13 ноября 2010

Если вы хотите сделать это таким образом, я думаю, что вместо этого лучше использовать условную компиляцию, поскольку вы можете сделать это внутри javascript без необходимости изменять html:

var isIE = /*@cc_on!@*/false;
26 голосов
/ 21 мая 2013

Ответ Марселя Корпеля больше не работает (в IE 10 он возвращает undef, поэтому IE 10 выглядит как не IE).ПРИМЕЧАНИЕ: теперь обновлено для работы с IE 11.

Это вариант этого кода, но он исходит из рекомендаций Microsoft .Если вы использовали предыдущий код, вы можете просто вставить эту замену, поскольку она создается так, чтобы вызываться точно так же.

В отличие от условных комментариев / компиляции, она также должна нормально работать с минимизаторами.

// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
// ie === undefined
// If you're in IE (>=5) then you can determine which version:
// ie === 7; // IE7
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9, IE10 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------
var ie = (function(){
    var undef,rv = -1; // Return value assumes failure.
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    var trident = ua.indexOf('Trident/');

    if (msie > 0) {
        // IE 10 or older => return version number
        rv = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    } else if (trident > 0) {
        // IE 11 (or newer) => return version number
        var rvNum = ua.indexOf('rv:');
        rv = parseInt(ua.substring(rvNum + 3, ua.indexOf('.', rvNum)), 10);
    }

    return ((rv > -1) ? rv : undef);
}());

обновлен для работы с IE11.Спасибо 'acarlon' за то, что он указал, что он не работает, и 'mario' за код, на котором я основал исправление!

11 голосов
/ 02 января 2014

IE 11 сильно изменился, и теперь многие прошлые методы обнаружения браузеров не работают.Приведенный ниже код работает для IE 11 и более ранних версий.

function isIE()
{
    var isIE11 = navigator.userAgent.indexOf(".NET CLR") > -1;      
    var isIE11orLess = isIE11 || navigator.appVersion.indexOf("MSIE") != -1;
    return isIE11orLess;
}
6 голосов
/ 21 октября 2012

Я думаю, у меня есть то, что вы ищете.Вы можете получить полную версию Internet Explorer в виде строки «AA.BB.CCCC.DDDD», используя Javascript и clientCaps.

http://www.pinlady.net/PluginDetect/IE/

Похоже, работает для IE 5.5 и выше(включая IE 10).Он невосприимчив к навигатору.userAgent / режиму документа / режиму браузера.Нет необходимости в условных комментариях или каких-либо дополнительных элементах HTML.Это чисто решение Javascript.

В настоящее время я не уверен, как себя ведет IE Mobile, но вы всегда можете использовать метод обнаружения резервных копий в случае сбоя метода clientCaps.

Пока чтоЯ должен сказать, что это работает довольно хорошо.

4 голосов
/ 13 ноября 2010

Я думаю, что вы ответили на свой собственный вопрос: во-первых, он обнаруживает только IE, поэтому сценарий, по сути, разделит вселенную браузеров на 2 части: IE и .

Во-вторых, вам нужно будет добавить дурацкий комментарий к каждой HTML-странице.Принимая во внимание, что широкие библиотеки JavaScript, такие как jQuery и YUI, должны быть «простыми» для вставки / использования для широкого спектра сайтов, вы автоматически усложняете их использование вне ворот.

3 голосов
/ 13 ноября 2010

navigator.userAgent существует, если действительно требуется обнаружение браузера (а не обнаружение функций), и jQuery использует его для получения информации для объекта $.browser.Это гораздо приятнее, чем включение условного комментария для IE в на каждой странице.

2 голосов
/ 16 июля 2013

Я использую этот код

var isIE = navigator.userAgent.indexOf ('MSIE')> -1;

2 голосов
/ 12 июля 2013
var version = navigator.userAgent.match(/(msie) (\d+)/i);
console.log(version);

что-то быстрое я написал быстро, посмотрев на этот вопрос, на случай, если кто-то захочет.

** РЕДАКТИРОВАТЬ **

За Комментарий Джонни Дарвалла ниже, я добавляю ссылку для всех, кто пытается перехватить Internet Explorer 11 :

http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx

2 голосов
/ 19 июня 2013

Здесь вы можете найти несколько действительно простых хаков для обнаружения в браузере: http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/

var isIE = IE='\v'=='v';
...