Как правильно использовать Modernizr для обнаружения IE?


84

Я хотел использовать библиотеку Modernizr JS для определения некоторых свойств браузера, чтобы определить, какой контент показывать или не показывать.

У меня есть приложение Pano2VR которое выводит как HTML5, так и SWF. Мне нужен HTML5 для пользователей устройств iOS.

Однако IE вообще не отображает этот вывод «HTML5». Похоже, в их выводе используются преобразования CSS3 3D и WebGL, один или несколько из которых явно не поддерживаются в IE9.

Итак, для этих пользователей мне нужно отобразить версию Flash. Я планировал использовать IFRAME и либо передать SRC через сценарий Modernizr, либо документ. Написать правильный код IFRAME в зависимости от браузера.

Все это приводит к тому, как мне использовать Modernizr для определения IE или не IE? Или обнаруживать преобразования CSS в 3d?

Или есть другой способ сделать это?

Ответы:


1

Я согласен, что мы должны проверить возможности, но трудно найти простой ответ на вопрос «какие возможности поддерживаются« современными браузерами », но не« старыми браузерами »?»

Итак, я запустил несколько браузеров и непосредственно изучил Modernizer. Я добавил несколько возможностей, которые мне определенно необходимы, а затем добавил «inputtypes.color», потому что он, кажется, охватывает все основные браузеры, которые меня интересуют: Chrome, Firefox, Opera, Edge ... и НЕ IE11. Теперь я могу мягко предположить, что пользователю было бы лучше с Chrome / Opera / Firefox / Edge.

Это то, что я использую - вы можете редактировать список вещей для проверки в вашем конкретном случае. Возвращает false, если какая-либо из возможностей отсутствует.

/**
 * Check browser capabilities.
 */
public CheckBrowser(): boolean
{
    let tests = ["csstransforms3d", "canvas", "flexbox", "webgl", "inputtypes.color"];

    // Lets see what each browser can do and compare...
    //console.log("Modernizr", Modernizr);

    for (let i = 0; i < tests.length; i++)
    {
        // if you don't test for nested properties then you can just use
        // "if (!Modernizr[tests[i]])" instead
        if (!ObjectUtils.GetProperty(Modernizr, tests[i]))
        {
            console.error("Browser Capability missing: " + tests[i]);
            return false;
        }
    }

    return true;
}

А вот и метод GetProperty, который нужен для "inputtypes.color".

/**
 * Get a property value from the target object specified by name.
 * 
 * The property name may be a nested property, e.g. "Contact.Address.Code".
 * 
 * Returns undefined if a property is undefined (an existing property could be null).
 * If the property exists and has the value undefined then good luck with that.
 */
public static GetProperty(target: any, propertyName: string): any
{
    if (!(target && propertyName))
    {
        return undefined;
    }

    var o = target;

    propertyName = propertyName.replace(/\[(\w+)\]/g, ".$1");
    propertyName = propertyName.replace(/^\./, "");

    var a = propertyName.split(".");

    while (a.length)
    {
        var n = a.shift();

        if (n in o)
        {
            o = o[n];

            if (o == null)
            {
                return undefined;
            }
        }
        else
        {
            return undefined;
        }
    }

    return o;
}

195

Modernizr не определяет браузеры как таковые, он определяет, какие функции и возможности присутствуют, и это все, что он пытается сделать.

Вы можете попробовать подключить такой простой скрипт обнаружения, а затем использовать его, чтобы сделать свой выбор. Я также включил обнаружение версий на всякий случай. Если вы хотите проверить только любую версию IE, вы можете просто найти navigator.userAgent, имеющий значение «MSIE».

var BrowserDetect = {
        init: function () {
            this.browser = this.searchString(this.dataBrowser) || "Other";
            this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";
        },
        searchString: function (data) {
            for (var i = 0; i < data.length; i++) {
                var dataString = data[i].string;
                this.versionSearchString = data[i].subString;

                if (dataString.indexOf(data[i].subString) !== -1) {
                    return data[i].identity;
                }
            }
        },
        searchVersion: function (dataString) {
            var index = dataString.indexOf(this.versionSearchString);
            if (index === -1) {
                return;
            }

            var rv = dataString.indexOf("rv:");
            if (this.versionSearchString === "Trident" && rv !== -1) {
                return parseFloat(dataString.substring(rv + 3));
            } else {
                return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
            }
        },

        dataBrowser: [
            {string: navigator.userAgent, subString: "Edge", identity: "MS Edge"},
            {string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},
            {string: navigator.userAgent, subString: "Trident", identity: "Explorer"},
            {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
            {string: navigator.userAgent, subString: "Opera", identity: "Opera"},  
            {string: navigator.userAgent, subString: "OPR", identity: "Opera"},  

            {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"}, 
            {string: navigator.userAgent, subString: "Safari", identity: "Safari"}       
        ]
    };
    
    BrowserDetect.init();
    document.write("You are using <b>" + BrowserDetect.browser + "</b> with version <b>" + BrowserDetect.version + "</b>");

Затем вы можете просто проверить:

BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;

2
Благодарю. Я наконец выяснил, что проблема заключалась в том, что их файл нуждался в поддержке webgl. Итак, я мог бы использовать Modernizer, чтобы проверить это и сделать document.write одного блока кода другого. Но это отличное решение для обнаружения браузером. Еще раз спасибо.
Steve

2
Следует помнить одну вещь: строка UA полностью настраивается пользователем. Таким образом, проверка строки UA НЕ является последовательным способом проверки браузера. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent В разделе «Примечания»:Browser identification based on detecting the user agent string is unreliable and is not recommended, as the user agent string is user configurable.
Эндрю Сеннер

51
Да, но какой процент пользователей просматривает веб-страницы с измененной / подделкой / неправильной строкой UA? Сколько времени на разработку вы хотите потратить на то, чтобы крошечное меньшинство получило оптимальный опыт работы на вашем сайте? Обнюхивание браузера через строку UA - практичный и разумный подход.
Джед Ричардс

17
@Wintamute, не могу не согласиться. Устали от лекций типа «обнаружение функций - зло». Мы занимаемся разработкой, а не
занимаемся

9
Это общее предположение, что если кто-то изменяет свою строку UA, он знает, что делает, и может справиться с последствиями. Фактически, это именно то, для чего существует строка UA - чтобы сообщить серверу версию браузера. Если клиент хочет солгать об этом, что ж, это просто жизнь! Конечно, существует небольшая вероятность того, что строка будет изменена без согласия пользователя, но на практике это не является серьезной проблемой - и, эй, мы должны кормить пользователя и тереть ему спину?
Rolf

20

Вы можете использовать Modernizr для обнаружения просто IE или не IE, проверив SVG SMIL поддержку анимации .

Если вы включили обнаружение функций SMIL в настройку Modernizr, вы можете использовать простой подход CSS и нацелить класс .no-smil, который Modernizr применяет к элементу html :

html.no-smil {
  /* IE/Edge specific styles go here - hide HTML5 content and show Flash content */
}

В качестве альтернативы вы можете использовать Modernizr с простым подходом JavaScript, например:

if ( Modernizr.smil ) {
  /* set HTML5 content */
} else {
  /* set IE/Edge/Flash content */
}

Имейте в виду, что IE / Edge когда-нибудь может поддерживать SMIL , но в настоящее время это не планируется.

Для справки, вот ссылка на таблицу совместимости SMIL на caniuse.com .


Лучший ответ имо. Так просто
Бэтмен

2
Хотя это действительно работает, на данный момент это работает. Весь смысл обнаружения функций и Modernizr в том, что вам не нужно беспокоиться о том, что произойдет завтра. Если завтра Edge обновится с поддержкой smil, ваш код больше не будет работать, и вы можете даже не знать об этом.
Джейсон


1
Это выглядело так просто, но, очевидно, Edge теперь поддерживает SMIL .
Джереми Карлсон

12

Обнаружение 3D-преобразований CSS

Modernizr может обнаруживать 3D-преобразования CSS , да. ПравдивостьModernizr.csstransforms3d скажет вам, поддерживает ли их браузер.

Вышеупомянутая ссылка позволяет вам выбрать, какие тесты включить в сборку Modernizr, и там будет доступен нужный вам вариант.


Обнаружение IE в частности

В качестве альтернативы , как ответил user356990, вы можете использовать условные комментарии, если ищете только IE и IE. Вместо создания глобальной переменной вы можете использовать <html>трюк условных комментариев HTML5 Boilerplate для назначения класса:

<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->

Если у вас уже инициализирован jQuery, вы можете просто проверить его с помощью $('html').hasClass('lt-ie9'). Если вам нужно проверить, в какой версии IE вы находитесь, чтобы можно было условно загрузить либо jQuery 1.x, либо 2.x, вы можете сделать что-то вроде этого:

myChecks.ltIE9 = (function(){
    var htmlElemClasses = document.querySelector('html').className.split(' ');
    if (!htmlElemClasses){return false;}
    for (var i = 0; i < htmlElemClasses.length; i += 1 ){
      var klass = htmlElemClasses[i];
      if (klass === 'lt-ie9'){
        return true;
      }
    }
    return false;
}());

NB. Условные комментарии IE поддерживаются только до IE9 включительно. Начиная с IE10, Microsoft рекомендует использовать обнаружение функций, а не обнаружение браузера.


Какой бы метод вы ни выбрали, вы должны протестировать

if ( myChecks.ltIE9 || Modernizr.csstransforms3d ){
    // iframe or flash fallback
} 

||Конечно, не воспринимайте это буквально.


Лично я всегда стараюсь выполнять обнаружение на основе функций, а не обнаружение браузера,
Крис,

@Chris Молодец, здесь тоже самое? Я ... не думаю, что вы действительно читали мой ответ.
iono

Ваш был первым ответом, который на самом деле предлагает использовать функцию обнаружения, поэтому решил, что это может помочь другому человеку, если он прочитает комментарий
Крис

@ Крис, извини. Я думал, вы меня осуждаете за включение теста IE.
iono

9

Если вы ищете JS-версию (с использованием комбинации обнаружения функций и сниффинга UA) того, для чего использовался шаблон html5:

var IE = (!! window.ActiveXObject && +(/msie\s(\d+)/i.exec(navigator.userAgent)[1])) || NaN;
if (IE < 9) {
    document.documentElement.className += ' lt-ie9' + ' ie' + IE;
}

3

Что ж, после дополнительных исследований по этой теме я решил использовать следующее решение для таргетинга на IE 10+. Поскольку IE10 и 11 - единственные браузеры, которые поддерживают медиа-запрос -ms-high-Contrast, это хороший вариант без JS:

@media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none) {  
   /* IE10+ specific styles go here */  
}

Прекрасно работает.


2

Уловки CSS есть хорошее решение для IE 11:

http://css-tricks.com/ie-10-specific-styles/

.NET и Trident / 7.0 уникальны для IE, поэтому могут использоваться для обнаружения IE версии 11.

Затем код добавляет строку User Agent в тег html с атрибутом data-useragent, так что IE 11 может быть специально нацелен ...


1

Мне нужно было обнаружить IE по сравнению с большинством всего остального, и я не хотел зависеть от строки UA. Я обнаружил, что используяes6number Modernizr делает именно то, что я хотел. Меня это не особо беспокоит, поскольку я не ожидаю, что IE когда-либо будет поддерживать ES6 Number. Итак, теперь я знаю разницу между любой версией IE и Edge / Chrome / Firefox / Opera / Safari.

Подробнее здесь: http://caniuse.com/#feat=es6-number

Обратите внимание, что меня не особо беспокоят ложные негативы Opera Mini. Вы, возможно.


0

Вы можете использовать этот < !-- [if IE] > прием для установки глобальной переменной js, которая затем будет протестирована в вашем обычном коде js. Немного некрасиво, но мне понравилось.


23
Условные комментарии больше не поддерживаются в Internet Explorer> = 10.
rudimenter
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.