Правильний спосіб використання 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 одного блоку коду іншого. Але це відмінне рішення для виявлення браузера. Знову дякую.
— Стів

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 - оголосити серверу версію браузера. Якщо клієнт хоче збрехати з цього приводу, то це просто життя! Звичайно, є невелика ймовірність зміни рядка без згоди користувача, але на практиці це не є справжнім занепокоєнням - і привіт, ми повинні годувати користувача і терти йому також спину?
— Рольф

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 .


Найкраща відповідь imo. Так просто
— Бетмен

2
Хоча це працює, поки що працює. Вся суть виявлення функцій та Modernizr полягає в тому, що вам не потрібно турбуватися про те, що станеться завтра. Якщо Edge оновиться завтра з підтримкою smil, ваш код більше не працює, і ви можете його навіть не знати.
— Джейсон,


1
Це виглядало так просто, але, очевидно, Edge тепер підтримує SMIL .
— Джеремі Карлсон,

12

Виявлення перетворень CSS 3D

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

Наведене вище посилання дозволяє вибрати тести, які потрібно включити до збірки Modernizr, і опція, яку ви шукаєте, доступна там.


Виявлення IE спеціально

Як варіант , як відповів користувач356990, ви можете використовувати умовні коментарі, якщо ви шукаєте 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;
}());

Умовні коментарі до IE підтримуються лише до IE9 включно. Починаючи з IE10, Microsoft заохочує використовувати виявлення функцій, а не виявлення браузером.


Який би метод ви не вибрали, тоді ви б протестували

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

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


Особисто я завжди намагаюся робити виявлення на основі функцій, а не виявлення браузером
— Кріс,

@Chris Добре вам, те саме тут? Я ... не думаю, що ви насправді прочитали мою відповідь.
— iono

Твоя була першою відповіддю, яка насправді пропонує використовувати функцію виявлення, тому вважали, що це може допомогти іншій людині, якщо вони прочитають коментар
— Кріс,

@Chris ой, вибач. Я думав, ви засуджуєте мене за те, що я включив тест 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-висококонтрастного медіа, це хороший варіант без жодної 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. Я виявив, що використання es6numberModernizr робило саме те, що я хотів. Я не дуже стурбований цією зміною, оскільки я не очікую, що IE коли-небудь підтримуватиме номер ES6. Тож тепер я знаю різницю між будь-якою версією IE від Edge / Chrome / Firefox / Opera / Safari.

Детальніше тут: http://caniuse.com/#feat=es6-number

Зауважте, що мене насправді не турбують фальшиві негативи Opera Mini. Ви можете бути.


0

Ви можете використовувати < !-- [if IE] > хак для встановлення глобальної змінної js, яка потім тестується у вашому звичайному js-коді. Трохи потворний, але добре в мене спрацював.


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