IE'yi tespit etmek için Modernizr'i kullanmanın doğru yolu?


84

Hangi içeriğin gösterilip gösterilmeyeceğini belirlemek üzere bazı tarayıcı özelliklerini tespit etmek için Modernizr JS kitaplığını kullanmak istedim.

Hem HTML5 hem de SWF çıkışı veren Pano2VR adında bir uygulamam var . İOS cihazı kullanıcıları için HTML5'e ihtiyacım var.

Ancak, IE bu "HTML5" çıktısını hiç oluşturmuyor. Görünüşe göre çıktıları IE9'da bir veya daha fazla desteklenmeyen CSS3 3D dönüşümleri ve WebGL kullanıyor.

Bu nedenle, bu kullanıcılar için Flash sürümünü görüntülemem gerekiyor. Bir IFRAME kullanmayı ve SRC'yi bir Modernizr komut dosyası veya belge aracılığıyla geçirmeyi planlıyordum. Tarayıcıya bağlı olarak doğru IFRAME kodunu yazın.

Bunların tümü, basitçe IE'yi veya IE'yi algılamamak için Modernizr'i nasıl kullanacağım? Veya CSS 3d dönüşümlerini tespit etmek mi?

Yoksa bunu yapmanın başka bir yolu var mı?

Yanıtlar:


1

Yetenekleri test etmemiz gerektiğini kabul ediyorum, ancak "hangi yetenekler 'modern tarayıcılar' tarafından destekleniyor, ancak 'eski tarayıcılar' tarafından desteklenmiyor?" Sorusuna basit bir yanıt bulmak zor.

Bu yüzden bir grup tarayıcıyı çalıştırdım ve Modernizer'ı doğrudan inceledim. Kesinlikle ihtiyaç duyduğum birkaç özellik ekledim ve ardından "inputtypes.color" ekledim çünkü bu ilgilendiğim tüm ana tarayıcıları kapsıyor: Chrome, Firefox, Opera, Edge ... ve IE11 DEĞİL. Artık kullanıcının Chrome / Opera / Firefox / Edge ile daha iyi durumda olacağını nazikçe önerebilirim.

Kullandığım şey bu - özel durumunuz için test edilecek şeylerin listesini düzenleyebilirsiniz. Yeteneklerden herhangi biri eksikse yanlış döndürür.

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

Ve işte "inputtypes.color" için gerekli olan GetProperty yöntemi.

/**
 * 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, tarayıcıları bu şekilde algılamaz, hangi özellik ve yeteneğin mevcut olduğunu algılar ve yapmaya çalıştığı şeyin tamamı budur.

Bunun gibi basit bir algılama betiğine bağlanmayı deneyebilir ve ardından seçiminizi yapmak için onu kullanabilirsiniz. Gerekirse Versiyon Algılamayı da dahil ettim. Yalnızca herhangi bir IE sürümünü kontrol etmek istiyorsanız, "MSIE" değerine sahip navigator.userAgent'ı arayabilirsiniz.

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

Daha sonra şunları kontrol edebilirsiniz:

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

2
Teşekkürler. Sonunda sorunun dosyalarının webgl desteğine ihtiyaç duyduğunu tespit ettim. Bunu test etmek ve bir kod bloğunun bir kod bloğunun bir document.write'ı yapmak için Modernizer'ı kullanabilirim. Ancak bu, tarayıcı tespiti için mükemmel bir çözümdür. Tekrar teşekkürler.
Steve

2
Unutulmaması gereken bir şey var: UA dizesi tamamen kullanıcı tarafından yapılandırılabilir .. Dolayısıyla, UA dizesini kontrol etmek, tarayıcıyı kontrol etmenin tutarlı bir yolu DEĞİLDİR. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent "Notlar" bölümünde: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
Evet, ancak kullanıcıların yüzde kaçı web'de değiştirilmiş / sahte / yanlış bir UA dizesiyle geziniyor? Küçük bir azınlığın sitenizde optimal bir deneyime sahip olmasını sağlamak için ne kadar mühendislik zamanı harcamak istiyorsunuz? UA dizisi aracılığıyla tarayıcı koklama pratik ve mantıklı bir yaklaşımdır.
Jed Richards

17
@Wintamute, daha fazla katılıyorum. "Özellik tespiti kötüdür" türden bir dersten sıkıl. Sanat peşinde değil, mühendislik yapıyoruz
Philip007

9
Genel bir varsayım, birisi UA dizesini değiştirirse, ne yaptığını bilir ve sonuçlarıyla başa çıkabilir. Aslında bu, tarayıcı sürümünü sunucuya bildirmek için UA dizesinin tam olarak var olduğu şeydir. Müşteri bu konuda yalan söylemek istiyorsa, o zaman bu sadece hayattır! Elbette, kullanıcının izni olmadan dizginin değişme olasılığı çok düşük, ancak pratikte bu gerçek bir endişe değil - ve kullanıcıyı besleyip sırtını da ovmamız mı gerekiyor?
Rolf

20

SVG SMIL animasyon desteğini kontrol ederek, basitçe IE'yi veya IE'yi algılamak için Modernizr'i kullanabilirsiniz .

Modernizr kurulumunuza SMIL özelliği algılamayı dahil ettiyseniz, basit bir CSS yaklaşımı kullanabilir ve Modernizr'in html öğesine uyguladığı .no-smil sınıfını hedefleyebilirsiniz :

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

Alternatif olarak, Modernizr'i aşağıdaki gibi basit bir JavaScript yaklaşımıyla kullanabilirsiniz:

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

Akılda Ayı IE / Kenar kudreti birgün destek SMIL , ama bunu yapmak için şu anda herhangi bir plan yapılmamıştır.

Referans için caniuse.com adresindeki SMIL uyumluluk tablosuna bir bağlantı burada .


En iyi cevap imo. Çok basit
Batman

2
Bu işe yarasa da şimdilik çalışıyor. Özellik algılamanın ve Modernizr'in tüm amacı, yarın ne olacağı konusunda endişelenmenize gerek olmamasıdır. Edge yarın smil desteğiyle güncellenirse, kodunuz artık çalışmaz ve siz bunu bilmiyor olabilirsiniz.
Jason


1
Bu çok basit görünüyordu, ancak görünüşe göre Edge artık SMIL'i destekliyor .
Jeremy Carlson

12

CSS 3B dönüşümlerini algılama

Modernizr , CSS 3D dönüşümlerini algılayabilir , evet. Doğruluğu Modernizr.csstransforms3d, tarayıcının onları destekleyip desteklemediğini size söyleyecektir.

Yukarıdaki bağlantı, bir Modernizr yapısına hangi testleri dahil edeceğinizi seçmenize izin verir ve aradığınız seçenek burada mevcuttur.


IE'yi özel olarak algılama

Alternatif olarak , user356990'ın yanıtladığı gibi, yalnızca IE ve IE'yi arıyorsanız koşullu açıklamaları kullanabilirsiniz. Global bir değişken oluşturmak yerine, <html>bir sınıf atamak için HTML5 Boilerplate'in koşullu yorum hilesini kullanabilirsiniz:

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

Zaten jQuery'yi başlattıysanız, sadece kontrol edebilirsiniz $('html').hasClass('lt-ie9'). Koşullu olarak jQuery 1.x veya 2.x yükleyebilmek için hangi IE sürümünü kullandığınızı kontrol etmeniz gerekiyorsa, aşağıdaki gibi bir şey yapabilirsiniz:

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 koşullu yorumları yalnızca IE9'a kadar desteklenir. IE10'dan itibaren Microsoft, tarayıcı algılaması yerine özellik algılamayı kullanmayı teşvik ediyor.


Hangi yöntemi seçerseniz seçin, daha sonra test edersiniz

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

||Elbette bunu tam anlamıyla almayın .


Şahsen ben her zaman tarayıcı algılama yerine özellik tabanlı algılama yapmayı deniyorum
Chris

@Chris Senin için iyi, burada da aynı mı? Ben ... gerçekten cevabımı okuduğunu sanmıyorum.
2014

Aslında özellik algılamayı kullanmayı öneren ilk cevap sizinki idi, bu yüzden yorumu
Chris

@Chris oh, özür dilerim. IE testini dahil ettiğim için beni kınadığını sanıyordum.
iono

9

Daha önce html5 standart metninin yaptığı şeyin bir JS sürümünü (özellik algılama ve UA koklama kombinasyonunu kullanarak) arıyorsanız:

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

3

Bu konu hakkında daha fazla araştırma yaptıktan sonra, IE 10+ hedeflemek için aşağıdaki çözümü kullandım. IE10 ve 11, -ms-yüksek kontrastlı ortam sorgusunu destekleyen tek tarayıcı olduğundan, bu, herhangi bir JS içermeyen iyi bir seçenektir:

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

Mükemmel çalışıyor.


2

CSS numaralarının IE 11'i hedeflemek için iyi bir çözümü vardır:

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

.NET ve Trident / 7.0, IE'ye özgüdür, bu nedenle IE sürüm 11'i algılamak için kullanılabilir.

Kod daha sonra Kullanıcı Aracısı dizesini html etiketine 'data-useragent' niteliğiyle ekler, böylece IE 11 özel olarak hedeflenebilir ...


1

IE'yi ve diğer her şeyi tespit etmem gerekiyordu ve UA dizesine bağlı olmak istemedim. es6numberModernizr ile kullanmanın tam olarak istediğimi yaptığını gördüm. IE'nin ES6 Numarasını desteklemesini beklemediğim için bu değişiklikle ilgili fazla endişem yok. Artık IE'nin herhangi bir sürümü ile Edge / Chrome / Firefox / Opera / Safari arasındaki farkı biliyorum.

Daha fazla ayrıntı burada: http://caniuse.com/#feat=es6-number

Opera Mini'nin yanlış negatifleri hakkında gerçekten endişelenmediğimi unutmayın. Olabilirsin.


0

< !-- [if IE] > Hack'i, daha sonra normal js kodunuzda test edilecek genel bir js değişkeni ayarlamak için kullanabilirsiniz . Biraz çirkin ama benim için iyi çalıştı.


23
Koşullu yorumlar internet explorer> = 10'da artık desteklenmemektedir.
rudimenter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.