Właściwy sposób używania Modernizr do wykrywania IE?

84

Chciałem użyć biblioteki Modernizr JS, aby wykryć niektóre właściwości przeglądarki, aby określić, jakie treści mają być wyświetlane, a jakie nie.

Mam aplikację o nazwie Pano2VR, która wyświetla zarówno HTML5, jak i SWF. Potrzebuję HTML5 dla użytkowników urządzeń z iOS.

Jednak IE w ogóle nie renderuje tego wyjścia „HTML5”. Wygląda na to, że ich dane wyjściowe wykorzystują transformacje CSS3 3D i WebGL, jeden lub więcej najwyraźniej nieobsługiwanych w IE9.

Tak więc dla tych użytkowników muszę wyświetlić wersję Flash. Planowałem użyć IFRAME i albo przekazać kod SRC za pomocą skryptu Modernizr, albo document. Wypisać poprawny kod IFRAME w zależności od przeglądarki.

Wszystko to prowadzi do tego, jak używać Modernizr do wykrywania po prostu IE lub nie IE? Lub wykryć transformacje CSS 3D?

Czy jest inny sposób, aby to zrobić?

Steve
źródło

Odpowiedzi:

1

Zgadzam się, że powinniśmy przetestować możliwości, ale trudno jest znaleźć prostą odpowiedź na pytanie „jakie funkcje są obsługiwane przez„ nowoczesne przeglądarki ”, ale nie przez„ stare przeglądarki ”?

Uruchomiłem więc kilka przeglądarek i bezpośrednio sprawdziłem Modernizera. Dodałem kilka funkcji, których zdecydowanie potrzebuję, a następnie dodałem „inputtypes.color”, ponieważ wydaje się, że obejmuje wszystkie najważniejsze przeglądarki, na których mi zależy: Chrome, Firefox, Opera, Edge ... a NIE IE11. Teraz mogę delikatnie zasugerować, że użytkownikowi byłoby lepiej z Chrome / Opera / Firefox / Edge.

Właśnie tego używam - możesz edytować listę rzeczy do przetestowania w swoim konkretnym przypadku. Zwraca wartość false, jeśli brakuje którejkolwiek funkcji.

/**
 * 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;
}

A oto ta metoda GetProperty, która jest potrzebna dla "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;
}
Etherman
źródło
195

Modernizr nie wykrywa przeglądarek jako takich, wykrywa obecne funkcje i możliwości i to jest cała jist tego, co próbuje zrobić.

Możesz spróbować podłączyć się do prostego skryptu wykrywającego, takiego jak ten, a następnie użyć go do dokonania wyboru. Dołączyłem również wykrywanie wersji na wypadek, gdyby było to potrzebne. Jeśli chcesz tylko sprawdzić jakąkolwiek wersję IE, możesz po prostu poszukać pliku navigator.userAgent o wartości „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>");

Następnie możesz po prostu sprawdzić:

BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;
Kod w wyjątkowy sposób
źródło
2
Dzięki. W końcu udało mi się ustalić, że problem polegał na tym, że ich plik wymagał wsparcia w sieci Web. Więc mógłbym użyć Modernizera do przetestowania tego i zrobić document.write jednego bloku kodu drugiego. Ale to doskonałe rozwiązanie do wykrywania przeglądarki. Dzięki jeszcze raz.
Steve,
2
Jedna rzecz do zapamiętania: ciąg znaków UA jest całkowicie konfigurowalny przez użytkownika. Zatem sprawdzenie ciągu znaków UA NIE jest spójnym sposobem sprawdzania przeglądarki. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent W sekcji „Uwagi”:Browser identification based on detecting the user agent string is unreliable and is not recommended, as the user agent string is user configurable.
Andrew Senner
51
Tak, ale jaki procent użytkowników przegląda sieć ze zmodyfikowanym / sfałszowanym / nieprawidłowym ciągiem znaków UA? Ile czasu inżynieryjnego chcesz poświęcić, aby niewielka mniejszość miała optymalne wrażenia z korzystania z Twojej witryny? Wąchanie przeglądarki za pomocą ciągu znaków UA jest praktycznym i rozsądnym podejściem.
Jed Richards
17
@Wintamute, nie mogę się bardziej zgodzić. Masz dość wykładów typu „wykrywanie funkcji jest złem”. Zajmujemy się inżynierią, a nie sztuką
Philip007
9
Jest ogólne założenie, że jeśli ktoś zmodyfikuje swój ciąg UA, to wie, co robi i może poradzić sobie z konsekwencjami. W rzeczywistości jest to dokładnie to, do czego służy ciąg UA - do zadeklarowania wersji przeglądarki na serwerze. Jeśli klient chce o tym kłamać, to cóż, takie jest życie! Oczywiście istnieje niewielka możliwość zmiany ciągu znaków bez zgody użytkownika, ale w praktyce to nie jest prawdziwy problem - a hej, czy mamy karmić użytkownika i masować jego plecy?
Rolf
20

Możesz użyć Modernizr, aby wykryć po prostu IE lub nie IE, sprawdzając obsługę animacji SVG SMIL .

Jeśli włączyłeś wykrywanie funkcji SMIL do swojej konfiguracji Modernizr, możesz użyć prostego podejścia CSS i wskazać klasę .no-smil, którą Modernizr stosuje do elementu html :

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

Alternatywnie, możesz użyć Modernizr z prostym podejściem JavaScript, na przykład:

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

Pamiętaj, że IE / Edge może pewnego dnia obsługiwać SMIL , ale obecnie nie ma takich planów.

Dla odniesienia, oto łącze do tabeli zgodności SMIL na caniuse.com .

jacefarm
źródło
Najlepsza odpowiedź imo. Takie proste
Batman
2
Chociaż to działa, na razie działa. Cały sens wykrywania funkcji i Modernizr polega na tym, że nie musisz się martwić o to, co stanie się jutro. Jeśli Edge zaktualizuje się jutro z obsługą smil, Twój kod przestanie działać i możesz nawet o tym nie wiedzieć.
Jason
Pozostaje, że nie ma planów dotyczących obsługi SMIL w Edge .
jacefarm
1
Wyglądało to tak prosto, ale najwyraźniej Edge obsługuje teraz SMIL .
Jeremy Carlson
12

Wykrywanie transformacji CSS 3D

Modernizr może wykrywać transformacje CSS 3D , tak. Prawdziwość Modernizr.csstransforms3dpowie Ci, czy przeglądarka je obsługuje.

Powyższe łącze umożliwia wybranie testów, które mają zostać uwzględnione w kompilacji Modernizr, a opcja, której szukasz, jest tam dostępna.


Wykrywanie w szczególności IE

Alternatywnie , jak odpowiedział user356990, możesz użyć komentarzy warunkowych, jeśli szukasz samych IE i IE. Zamiast tworzyć zmienną globalną, możesz użyć <html>sztuczki z komentarzami warunkowymi HTML5 Boilerplate do przypisania klasy:

<!--[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]-->

Jeśli masz już zainicjalizowane jQuery, możesz po prostu sprawdzić za pomocą $('html').hasClass('lt-ie9'). Jeśli chcesz sprawdzić, w której wersji IE jesteś, aby móc warunkowo załadować jQuery 1.x lub 2.x, możesz zrobić coś takiego:

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;
}());

Uwaga warunkowe komentarze IE są obsługiwane tylko do IE9 włącznie. Począwszy od IE10, Microsoft zachęca do używania wykrywania funkcji zamiast wykrywania przeglądarki.


Niezależnie od wybranej metody, należy przeprowadzić test

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

||Oczywiście nie bierz tego dosłownie.

iono
źródło
Osobiście zawsze staram się wykrywać na podstawie funkcji, a nie na wykrywaniu przeglądarki
Chris
@Chris Dobre dla ciebie, to samo tutaj? Myślę, że nie czytasz mojej odpowiedzi.
iono
Twoja była pierwszą odpowiedzią, która faktycznie sugeruje użycie wykrywania funkcji, więc pomyślałem, że może pomóc innej osobie, jeśli przeczyta komentarz
Chris
@Chris oh, przepraszam. Myślałem, że potępiasz mnie za włączenie testu IE.
iono
9

Jeśli szukasz wersji JS (wykorzystującej połączenie wykrywania funkcji i węszenia UA) tego, do czego służył standardowy szablon HTML5:

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

Cóż, po przeprowadzeniu dalszych badań na ten temat, ostatecznie użyłem następującego rozwiązania do kierowania na IE 10+. Ponieważ IE10 i 11 są jedynymi przeglądarkami obsługującymi zapytanie o media -ms-high-kontrast, jest to dobra opcja bez żadnego JS:

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

Działa świetnie.

Oliver White
źródło
2

Sztuczki CSS mają dobre rozwiązanie dla IE 11:

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

NET i Trident / 7.0 są unikalne dla IE, więc mogą być używane do wykrywania wersji IE 11.

Następnie kod dodaje ciąg User Agent do tagu html z atrybutem „data-useragent”, dzięki czemu IE 11 może być ukierunkowany konkretnie ...

Julian Veling
źródło
1

Musiałem wykryć IE w porównaniu z większością innych rzeczy i nie chciałem polegać na łańcuchu UA. Odkryłem, że używanie es6numberz Modernizr robi dokładnie to, czego chciałem. Nie przejmuję się tą zmianą, ponieważ nie oczekuję, że IE kiedykolwiek będzie obsługiwać numer ES6. Więc teraz znam różnicę między dowolną wersją IE a Edge / Chrome / Firefox / Opera / Safari.

Więcej szczegółów tutaj: http://caniuse.com/#feat=es6-number

Zauważ, że tak naprawdę nie martwię się fałszywymi negatywami Opery Mini. Mógłbyś być.

Splaktar
źródło
0

Możesz użyć < !-- [if IE] > hackowania, aby ustawić globalną zmienną js, która następnie zostanie przetestowana w normalnym kodzie js. Trochę brzydka, ale dobrze mi się sprawdziła.

crazy4groovy
źródło
23
Komentarze warunkowe nie są bardziej obsługiwane w programie Internet Explorer> = 10.
rudimenter