Javascript IE обнаружения, почему бы не использовать простые условные комментарии?

Чтобы обнаружить 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)
   ...

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


FYI: Я знаю, что лучше использовать обнаружение объекта, а не обнаружение браузера, но бывают случаи, когда вам все еще нужно использовать обнаружение браузера.

Ответ 1

Джеймс Падольси добавил небольшой фрагмент на 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;

}());

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

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

Ответ 2

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

var isIE = /*@[email protected]*/false;

Ответ 3

Ответ Marcel Korpel больше не работает (в 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" для кода, на котором я основал исправление!

Ответ 4

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

function isIE()
{
    var isIE11 = navigator.userAgent.indexOf(".NET CLR") > -1;      
    var isIE11orLess = isIE11 || navigator.appVersion.indexOf("MSIE") != -1;
    return isIE11orLess;
}

Ответ 5

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

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

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

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

До сих пор, я должен сказать, это работает очень хорошо.

Ответ 6

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

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

Ответ 7

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

Ответ 9

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

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

Ответ 10

Проверка для браузеров - плохая идея - лучше проверить функции браузера. Например, обычно вы проверяете, использует ли пользователь IE, потому что вы хотите использовать некоторую функцию, не поддерживаемую в IE. Однако вы можете знать, что ВСЕ текущие и будущие браузеры, не являющиеся IE, будут поддерживать эту функцию? Нет. Так, например, способ, например. используется jQuery лучше: он создает и выполняет небольшие проверки тестовых файлов для определенных ошибок/функций - и вы можете просто проверять такие вещи, как if (browser_supports_XYZ), а не проверять, использует ли пользователь определенный браузер.

Во всяком случае, всегда есть случаи, когда проверка браузера необходима, потому что это визуальная ошибка, которую вы не можете проверить для использования script. В этом случае лучше использовать javascript вместо условных комментариев, потому что у вас есть проверка браузера прямо в том месте, где вам это нужно, а не в каком-либо другом месте (представьте файл .js, где вы проверяете isIE, который никогда не определяется в этом файле )

Ответ 11

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

Ответ 12

В моем случае использования мне просто нужно определить, ниже IE9, поэтому я использую

if (document.body.style.backgroundSize === undefined && navigator.userAgent.indexOf('MSIE') > -1)
{
//IE8- stuff
}

Ответ 13

Почему бы вам просто не запрограммировать HTML5 и проверить, что

if ( window.navigator.product !== "Gecko" )

?? Правда, это будет включать IE11 в связку "Gecko", но разве он не должен быть достаточно хорошим сейчас?

Примечание: спецификация HTML5. говорит, что navigator.product должен возвращать "Gecko"... и IE10 и раньше все возвращают что-то еще.

Ответ 14

  • Он загрязняет глобальное пространство имен
  • Он требует изменений в двух файлах.
  • Он работает только в IE
  • Технически, условный комментарий по-прежнему остается комментарием

Ответ 15

Это работает неплохо,
var isIe = !!window.ActiveXObject;