Modo corretto di utilizzare Modernizr per rilevare IE?


84

Volevo utilizzare la libreria Modernizr JS per rilevare alcune proprietà del browser per determinare quale contenuto mostrare o non mostrare.

Ho un'app chiamata Pano2VR che genera sia HTML5 che SWF. Ho bisogno dell'HTML5 per gli utenti di dispositivi iOS.

Tuttavia, IE non esegue affatto il rendering di questo output "HTML5". Sembra che il loro output utilizzi trasformazioni 3D CSS3 e WebGL, una o più apparentemente non supportate in IE9.

Quindi, per quegli utenti ho bisogno di visualizzare la versione Flash. Avevo intenzione di utilizzare un IFRAME e passare l'SRC tramite uno script Modernizr o un documento. Scrivi il codice IFRAME corretto a seconda del browser.

Tutto ciò porta a come utilizzo Modernizr per rilevare semplicemente IE o non IE? O rilevare per trasformazioni 3D CSS?

O c'è un altro modo per farlo?

Risposte:


1

Sono d'accordo che dovremmo testare le capacità, ma è difficile trovare una risposta semplice a "quali funzionalità sono supportate dai" browser moderni "ma non dai" vecchi browser "?"

Quindi ho avviato un sacco di browser e ho controllato direttamente Modernizer. Ho aggiunto alcune funzionalità di cui ho decisamente bisogno, e poi ho aggiunto "inputtypes.color" perché sembra coprire tutti i principali browser che mi interessano: Chrome, Firefox, Opera, Edge ... e NON IE11. Ora posso suggerire gentilmente che l'utente starebbe meglio con Chrome / Opera / Firefox / Edge.

Questo è ciò che uso: puoi modificare l'elenco delle cose da testare per il tuo caso particolare. Restituisce false se manca una delle funzionalità.

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

Ed ecco quel metodo GetProperty che è necessario per "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 non rileva i browser in quanto tali, rileva quali funzionalità e capacità sono presenti e questo è l'intero succo di ciò che sta cercando di fare.

Potresti provare ad agganciare un semplice script di rilevamento come questo e poi usarlo per fare la tua scelta. Ho incluso anche il rilevamento della versione nel caso in cui fosse necessario. Se vuoi controllare solo una qualsiasi versione di IE, puoi semplicemente cercare navigator.userAgent con un valore "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>");

Puoi quindi semplicemente verificare:

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

2
Grazie. Alla fine ho scoperto che il problema era che il loro file necessitava del supporto webgl. Quindi, potrei usare Modernizer per testarlo e fare un document.write di un blocco di codice dell'altro. Ma questa è un'ottima soluzione per il rilevamento del browser. Grazie ancora.
Steve

2
Una cosa da ricordare: la stringa UA è completamente configurabile dall'utente. Quindi controllare la stringa UA NON è un modo coerente per controllare il browser. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent Nella sezione "Note":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
Sì, ma quale percentuale di utenti naviga sul Web con una stringa UA modificata / falsificata / errata? Quanto tempo di progettazione vuoi dedicare a garantire che una piccola minoranza abbia un'esperienza ottimale sul tuo sito? Lo sniffing del browser tramite la stringa UA è un approccio pratico e sensato.
Jed Richards

17
@ Wintamute, non posso essere più d'accordo. Stanchi di una lezione tipo "il rilevamento delle funzionalità è malvagio". Stiamo facendo ingegneria, non perseguendo l'arte
Philip007

9
È il presupposto generale che se qualcuno modifica la propria stringa UA, sa cosa sta facendo e può affrontare le conseguenze. In realtà questo è esattamente ciò per cui esiste la stringa UA: per dichiarare la versione del browser al server. Se il cliente vuole mentire su questo, allora è solo la vita! Ovviamente c'è una piccola possibilità che la stringa venga modificata senza il consenso dell'utente, ma in pratica non è una vera preoccupazione - e ehi dovremmo dare da mangiare all'utente e strofinargli anche la schiena?
Rolf

20

Puoi utilizzare Modernizr per rilevare semplicemente IE o meno IE, controllando il supporto dell'animazione SVG SMIL .

Se hai incluso il rilevamento della funzionalità SMIL nella tua configurazione Modernizr, puoi utilizzare un semplice approccio CSS e indirizzare la classe .no-smil che Modernizr applica all'elemento html :

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

In alternativa, puoi usare Modernizr con un semplice approccio JavaScript, in questo modo:

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

Ricorda che IE / Edge potrebbe un giorno supportare SMIL , ma al momento non ci sono piani per farlo.

Per riferimento, ecco un collegamento alla tabella di compatibilità SMIL su caniuse.com .


Migliore risposta imo. Così semplice
Batman

2
Sebbene funzioni, per ora funziona. Il punto centrale del rilevamento delle funzionalità e di Modernizr è che non devi preoccuparti di ciò che accadrà domani. Se Edge si aggiorna domani con il supporto smil, il tuo codice non funziona più e potresti anche non saperlo.
Jason


1
Sembrava così semplice, ma a quanto pare Edge ora supporta SMIL .
Jeremy Carlson

12

Rilevamento delle trasformazioni CSS 3D

Modernizr può rilevare le trasformazioni CSS 3D , sì. La veridicità diModernizr.csstransforms3d ti dirà se il browser li supporta.

Il collegamento sopra ti consente di selezionare quali test includere in una build Modernizr e l'opzione che stai cercando è disponibile lì.


Rilevamento specifico di IE

In alternativa , come ha risposto user356990, puoi utilizzare commenti condizionali se stai cercando IE e IE da soli. Invece di creare una variabile globale, puoi utilizzare il <html>trucco dei commenti condizionali di HTML5 Boilerplate per assegnare una classe:

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

Se hai già inizializzato jQuery, puoi semplicemente controllare con $('html').hasClass('lt-ie9'). Se devi controllare quale versione di IE ti trovi in ​​modo da poter caricare in modo condizionale jQuery 1.x o 2.x, puoi fare qualcosa del genere:

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 I commenti condizionali di IE sono supportati solo fino a IE9 incluso. Da IE10 in poi, Microsoft incoraggia l'utilizzo del rilevamento delle funzionalità piuttosto che del rilevamento del browser.


Qualunque metodo tu scelga, dovresti quindi testarlo

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

Non prenderlo alla ||lettera, ovviamente.


Personalmente cerco sempre di eseguire il rilevamento basato sulle funzionalità piuttosto che il rilevamento del browser
Chris

@ Chris Buon per te, lo stesso qui? Io ... non credo che tu abbia davvero letto la mia risposta.
iono

La tua è stata la prima risposta che in realtà suggerisce di utilizzare il rilevamento delle funzionalità, quindi ho pensato che avrebbe potuto aiutare un'altra persona se avesse letto il commento
Chris

@ Chris oh, scusa. Pensavo mi stessi condannando per aver incluso il test IE.
iono

9

Se stai cercando una versione JS (utilizzando una combinazione di rilevamento delle funzionalità e sniffing UA) di ciò che faceva il boilerplate 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

Bene, dopo aver fatto ulteriori ricerche su questo argomento, ho finito per utilizzare la seguente soluzione per il targeting di IE 10+. Poiché IE10 e 11 sono gli unici browser che supportano la query multimediale -ms ad alto contrasto, questa è una buona opzione senza alcun JS:

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

Funziona perfettamente.


2

I trucchi CSS hanno una buona soluzione per indirizzare IE 11:

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

.NET e Trident / 7.0 sono esclusivi di IE, quindi possono essere utilizzati per rilevare la versione 11 di IE.

Il codice quindi aggiunge la stringa User Agent al tag html con l'attributo 'data-useragent', in modo che IE 11 possa essere mirato specificamente ...


1

Avevo bisogno di rilevare IE rispetto a quasi tutto il resto e non volevo dipendere dalla stringa UA. L'ho scoperto usandoes6number con Modernizr ha fatto esattamente quello che volevo. Non mi preoccupo molto di questo cambiamento perché non mi aspetto che IE supporti mai il numero ES6. Quindi ora conosco la differenza tra qualsiasi versione di IE vs Edge / Chrome / Firefox / Opera / Safari.

Maggiori dettagli qui: http://caniuse.com/#feat=es6-number

Nota che non sono molto preoccupato per i falsi negativi di Opera Mini. Potresti essere.


0

Puoi usare l' < !-- [if IE] > hack per impostare una variabile js globale che poi viene testata nel tuo normale codice js. Un po 'brutto ma ha funzionato bene per me.


23
I commenti condizionali non sono più supportati in Internet Explorer> = 10.
rudimenter
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.