Richtige Verwendung von Modernizr zur Erkennung von IE?

84

Dies mag eine dumme Frage sein, aber ich wollte die JS-Bibliothek von Modernizr verwenden, um anhand einiger Browsereigenschaften festzustellen, welche Inhalte angezeigt oder nicht angezeigt werden sollen.

Ich habe eine App namens Pano2VR, die sowohl HTML5 als auch SWF ausgibt. Ich benötige HTML5 für Benutzer von iOS-Geräten.

Der IE rendert diese "HTML5" -Ausgabe jedoch überhaupt nicht. Es scheint, dass ihre Ausgabe CSS3 3D-Transformationen und WebGL verwendet, eine oder mehrere, die in IE9 anscheinend nicht unterstützt werden.

Für diese Benutzer muss ich also die Flash-Version anzeigen. Ich hatte vor, einen IFRAME zu verwenden und den SRC entweder über ein Modernizr-Skript oder ein Dokument zu übergeben. Schreiben Sie je nach Browser den richtigen IFRAME-Code aus.

All dies führt dazu, wie ich Modernizr verwende, um einfach IE zu erkennen oder nicht IE? Oder für CSS 3d Transformationen erkennen?

Oder gibt es einen anderen Weg, dies zu tun?

Steve
quelle

Antworten:

0

Ich bin damit einverstanden, dass wir auf Funktionen testen sollten, aber es ist schwierig, eine einfache Antwort auf "Welche Funktionen werden von" modernen Browsern ", aber nicht von" alten Browsern "unterstützt?" Zu finden.

Also habe ich eine Reihe von Browsern gestartet und Modernizer direkt inspiziert. Ich habe ein paar Funktionen hinzugefügt, die ich definitiv benötige, und dann "inputtypes.color" hinzugefügt, da dies alle wichtigen Browser abzudecken scheint, die mir wichtig sind: Chrome, Firefox, Opera, Edge ... und NICHT IE11. Jetzt kann ich sanft vorschlagen, dass der Benutzer mit Chrome / Opera / Firefox / Edge besser dran wäre.

Dies ist, was ich benutze - Sie können die Liste der Dinge bearbeiten, die für Ihren speziellen Fall getestet werden sollen. Gibt false zurück, wenn eine der Funktionen fehlt.

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

Und hier ist die GetProperty-Methode, die für "inputtypes.color" benötigt wird.

/**
 * 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
quelle
195

Modernizr erkennt keine Browser als solche, es erkennt, welche Funktionen und Fähigkeiten vorhanden sind, und dies ist der ganze Kern dessen, was es zu tun versucht.

Sie können versuchen, ein einfaches Erkennungsskript wie dieses einzuhängen und es dann zu verwenden, um Ihre Wahl zu treffen. Ich habe auch die Versionserkennung aufgenommen, falls dies erforderlich ist. Wenn Sie nur eine Version des IE überprüfen möchten, können Sie einfach nach navigator.userAgent mit dem Wert "MSIE" suchen.

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>");

Sie können dann einfach prüfen nach:

BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;
Code eindeutig
quelle
2
Vielen Dank. Ich fand schließlich heraus, dass das Problem darin bestand, dass die Datei Webgl-Unterstützung benötigte. Also könnte ich Modernizer verwenden, um das zu testen und ein document.write von einem Codeblock des anderen zu machen. Dies ist jedoch eine hervorragende Lösung für die Browsererkennung. Danke noch einmal.
Steve
2
Eines ist zu beachten: Die UA-Zeichenfolge kann vollständig vom Benutzer konfiguriert werden. Das Überprüfen der UA-Zeichenfolge ist daher KEINE konsistente Methode zum Überprüfen des Browsers. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent Im Abschnitt "Notizen":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
Ja, aber wie viel Prozent der Benutzer surfen mit einer geänderten / gefälschten / falschen UA-Zeichenfolge im Internet? Wie viel Engineering-Zeit möchten Sie aufwenden, um sicherzustellen, dass eine winzige Minderheit auf Ihrer Site ein optimales Erlebnis hat? Browser-Sniffing über UA-String ist ein praktischer und vernünftiger Ansatz.
Jed Richards
17
@ Winamute, kann nicht mehr zustimmen. Haben Sie es satt, "Feature Detection is Evil" -Vortrag zu halten. Wir machen Ingenieurwesen, verfolgen keine Kunst
Philip007
8
Es ist die allgemeine Annahme, dass jemand, der seine UA-Zeichenfolge ändert, weiß, was er tut, und mit den Konsequenzen umgehen kann. Genau dafür existiert die UA-Zeichenfolge - um dem Server die Browserversion zu deklarieren. Wenn der Klient darüber lügen will, dann ist das nur das Leben! Natürlich gibt es eine kleine Möglichkeit, dass die Zeichenfolge ohne Zustimmung des Benutzers geändert wird, aber in der Praxis ist das kein wirkliches Problem - und hey, sollen wir den Benutzer füttern und ihm auch den Rücken reiben?
Rolf
19

Sie können Modernizr verwenden , um einfach IE oder nicht IE zu erkennen, indem Sie nach SVG SMIL- Animationsunterstützung suchen.

Wenn Sie die Erkennung von SMIL- Funktionen in Ihr Modernizr-Setup aufgenommen haben, können Sie einen einfachen CSS-Ansatz verwenden und auf die .no-smil- Klasse abzielen, die Modernizr auf das HTML- Element anwendet :

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

Alternativ können Sie Modernizr mit einem einfachen JavaScript-Ansatz verwenden, wie folgt:

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

Bedenken Sie, dass IE / Edge eines Tages möglicherweise SMIL unterstützen , dies ist jedoch derzeit nicht geplant.

Als Referenz finden Sie hier einen Link zur SMIL- Kompatibilitätstabelle unter caniuse.com .

Jacefarm
quelle
Beste Antwort imo. So einfach
Batman
2
Während dies funktioniert, funktioniert es vorerst. Der springende Punkt bei der Feature-Erkennung und bei Modernizr ist, dass Sie sich keine Gedanken darüber machen müssen, was morgen passiert. Wenn Edge morgen mit Smil-Unterstützung aktualisiert wird, funktioniert Ihr Code nicht mehr und Sie wissen es möglicherweise nicht einmal.
Jason
Es gibt weiterhin keine Pläne für SMIL-Unterstützung in Edge .
Jacefarm
12

Erkennen von CSS 3D-Transformationen

Modernizr kann CSS-3D-Transformationen erkennen , ja. Die Wahrhaftigkeit von Modernizr.csstransforms3dwird Ihnen sagen, ob der Browser sie unterstützt.

Über den obigen Link können Sie auswählen, welche Tests in einen Modernizr-Build aufgenommen werden sollen. Dort steht die gesuchte Option zur Verfügung.


IE spezifisch erkennen

Alternativ können Sie , wie user356990 antwortete, bedingte Kommentare verwenden, wenn Sie nur nach IE und IE suchen. Anstatt eine globale Variable zu erstellen, können Sie den <html>Trick für bedingte Kommentare von HTML5 Boilerplate verwenden , um eine Klasse zuzuweisen:

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

Wenn Sie jQuery bereits initialisiert haben, können Sie dies einfach überprüfen $('html').hasClass('lt-ie9'). Wenn Sie überprüfen müssen, in welcher IE-Version Sie sich befinden, damit Sie entweder jQuery 1.x oder 2.x bedingt laden können, können Sie Folgendes tun:

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-bedingte Kommentare werden nur bis einschließlich IE9 unterstützt. Ab IE10 empfiehlt Microsoft die Verwendung der Funktionserkennung anstelle der Browsererkennung.


Welche Methode Sie auch wählen, Sie würden sie dann testen

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

Nehmen Sie das ||natürlich nicht wörtlich.

iono
quelle
Persönlich versuche ich immer, eine funktionsbasierte Erkennung anstelle einer Browsererkennung durchzuführen
Chris
@ Chris Gut für dich, gleich hier? Ich glaube nicht, dass du meine Antwort tatsächlich gelesen hast.
Iono
Ihre war die erste Antwort, die tatsächlich die Verwendung von Feature Detect vorschlägt, so dass angenommen wird, dass es einer anderen Person helfen könnte, wenn sie den Kommentar liest
Chris
@ Chris oh, sorry. Ich dachte, Sie verurteilen mich, weil ich den IE-Test aufgenommen habe.
Iono
9

Wenn Sie nach einer JS-Version (mit einer Kombination aus Feature-Erkennung und UA-Sniffing) suchen, für die HTML5-Boilerplate verwendet wurde:

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.
quelle
3

Nachdem ich mehr zu diesem Thema recherchiert hatte, verwendete ich die folgende Lösung für das Targeting von IE 10+. Da IE10 und 11 die einzigen Browser sind, die die kontrastreiche Medienabfrage -ms unterstützen, ist dies eine gute Option ohne JS:

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

Funktioniert perfekt.

Oliver White
quelle
2

CSS-Tricks bieten eine gute Lösung für IE 11:

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

.NET und Trident / 7.0 sind nur für den Internet Explorer verfügbar und können daher zur Erkennung der IE-Version 11 verwendet werden.

Der Code fügt dann die HTML-Zeichenfolge des Benutzeragenten mit dem Attribut 'data-useragent' zum HTML-Tag hinzu, sodass IE 11 gezielt ...

Julian Veling
quelle
1

Sie können den < !-- [if IE] > Hack verwenden, um eine globale js-Variable festzulegen, die dann in Ihrem normalen js-Code getestet wird. Ein bisschen hässlich, hat aber bei mir gut funktioniert.

crazy4groovy
quelle
23
Bedingte Kommentare werden im Internet Explorer> = 10 nicht mehr unterstützt.
Rudimenter
1

Ich musste IE gegen fast alles andere erkennen und wollte mich nicht auf die UA-Zeichenfolge verlassen. Ich fand, dass die Verwendung es6numbermit Modernizr genau das tat, was ich wollte. Ich habe nicht viel Bedenken mit dieser Änderung, da ich nicht erwarte, dass der IE jemals die ES6-Nummer unterstützt. Jetzt kenne ich den Unterschied zwischen einer beliebigen Version von IE und Edge / Chrome / Firefox / Opera / Safari.

Weitere Details hier: http://caniuse.com/#feat=es6-number

Beachten Sie, dass ich mir keine Sorgen über falsche Negative von Opera Mini mache. Du könntest sein.

Splaktar
quelle