Modernizrを使用してIEを検出する正しい方法は?


84

Modernizr JSライブラリを使用して、いくつかのブラウザプロパティを検出し、表示するコンテンツと表示しないコンテンツを決定したいと思いました。

HTML5とSWFの両方を出力するPano2VRというアプリがあります。iOSデバイスユーザーにはHTML5が必要です。

ただし、IEはこの「HTML5」出力をまったくレンダリングしません。それらの出力はCSS33D変換とWebGLを使用しているようですが、IE9では明らかにサポートされていないものが1つ以上あります。

したがって、それらのユーザーのために、Flashバージョンを表示する必要があります。私はIFRAMEを使用することを計画しており、Modernizrスクリプトまたはdocument.writeを介してSRCを渡し、ブラウザーに応じて正しいIFRAMEコードを書き出します。

これらすべてが、Modernizrを使用してIEを単純に検出するかIEを検出しないかを決定する方法につながりますか?または、CSS 3D変換を検出しますか?

または、これを行う別の方法はありますか?

回答:


1

機能をテストする必要があることに同意しますが、「「最新のブラウザ」ではサポートされているが「古いブラウザ」ではサポートされていない機能」に対する簡単な答えを見つけるのは困難です。

それで、私はたくさんのブラウザを起動し、Modernizerを直接調べました。絶対に必要な機能をいくつか追加してから、「inputtypes.color」を追加しました。これは、IE11ではなくChrome、Firefox、Opera、Edgeなどの主要なブラウザすべてをカバーしているように見えるためです。これで、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;
}

そして、これが「inputtypes.color」に必要なGetPropertyメソッドです。

/**
 * 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のいずれかのバージョンのみを確認したい場合は、値が「MSIE」のnavigator.userAgentを探すだけです。

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
覚えておくべきことの1つ: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.
Andrew Senner

51
はい。ただし、UA文字列が変更された/なりすまされた/正しくない状態でWebを閲覧しているユーザーの割合は何パーセントですか?少数派がサイトで最適なエクスペリエンスを提供できるようにするために、どのくらいのエンジニアリング時間を費やしたいですか?UA文字列を介したブラウザスニッフィングは、実用的で健全なアプローチです。
Jed Richards

17
@Wintamute、これ以上同意できません。「特徴検出は悪」というような講義にうんざりする。私たちは芸術を追求するのではなく、エンジニアリングを行っています
Philip007 2013

9
誰かがUA文字列を変更した場合、彼らは自分が何をしているかを知っており、その結果に対処できるというのが一般的な仮定です。実際、これはまさにUA文字列が存在するものです-サーバーにブラウザのバージョンを宣言します。クライアントがそれについて嘘をつきたいのなら、まあ、それはただの人生です!もちろん、ユーザーの同意なしに文字列が変更される可能性はわずかですが、実際にはそれは実際の問題ではありません-そして、ユーザーに餌を与えて背中をこすることになっていますか?
rolf

20

Modernizrを使用して、SVG SMILアニメーションのサポートを確認することにより、IEを検出するかどうかを簡単に検出できます。

ModernizrセットアップにSMIL特徴検出を含めた場合は、単純なCSSアプローチを使用して、Modernizrがhtml要素に適用する.no-smilクラスをターゲットにすることができます。

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

または、次のような単純なJavaScriptアプローチでModernizrを使用することもできます。

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

IE / EdgeはいつかSMILをサポートする可能性があることを覚えておいてください。しかし、現在、サポートする予定はありません。

参考までに、caniuse.comのSMIL互換性チャートへのリンクを示します。


ベストアンサーイモ。とてもシンプル
バットマン

2
これは機能しますが、今のところは機能します。特徴検出とModernizrの要点は、明日何が起こるかを心配する必要がないということです。Edgeが明日smilサポートで更新されると、コードは機能しなくなり、知らないかもしれません。
ジェイソン


1
これはとても単純に見えましたが、どうやらEdgeはSMILをサポートするようになりました
ジェレミーカールソン

12

CSS3D変換の検出

ModernizrはCSS3D変換を検出できます。の真実性はModernizr.csstransforms3d、ブラウザがそれらをサポートしているかどうかを教えてくれます。

上記のリンクを使用すると、Modernizrビルドに含めるテストを選択でき、探しているオプションがそこで利用できます。


IEを具体的に検出する

または、user356990が回答したように、IEとIEのみを検索する場合は、条件付きコメントを使用できます。グローバル変数を作成する代わりに、HTML5Boilerplateの<html>条件付きコメントトリックを使用してクラスを割り当てることができます。

<!--[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')。jQuery 1.xまたは2.xのいずれかを条件付きでロードできるように、現在のIEバージョンを確認する必要がある場合は、次のようにすることができます。

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条件付きコメントは、IE9までしかサポートされていません。IE10以降、Microsoftは、ブラウザー検出ではなく機能検出を使用することを推奨しています。


どちらの方法を選択しても、次の方法でテストします。

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

||もちろん、それを文字通りに受け取らないでください。


個人的には、ブラウザの検出ではなく、機能ベースの検出を常に試みています
Chris

@クリスあなたに良い、ここでも同じ?私は...あなたが実際に私の答えを読んだとは思わない。
iono 2014年

あなたの答えは、機能検出の使用を実際に提案する最初の答えだったので、コメントを読んだら他の人に役立つかもしれないと考えました
Chris

@クリスああ、ごめんなさい。IEテストを含めたことで私を非難していると思いました。
iono 2014年

9

html5ボイラープレートが行っていたもののJSバージョン(特徴検出とUAスニッフィングの組み合わせを使用)を探している場合:

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

3

さて、このトピックについてさらに調査した後、私はIE10 +をターゲットにするために次のソリューションを使用することになりました。IE10&11は-ms-high-contrastメディアクエリをサポートする唯一のブラウザであるため、JSがない場合に適したオプションです。

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

完璧に動作します。


2

CSSのトリックには、IE11をターゲットにするための優れたソリューションがあります。

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

.NETおよびTrident / 7.0はIEに固有であるため、IEバージョン11の検出に使用できます。

次に、コードはユーザーエージェント文字列を属性「data-useragent」を使用してhtmlタグに追加するため、IE11を具体的にターゲットにできます...


1

IEと他のほとんどすべてを検出する必要があり、UA文字列に依存したくありませんでした。es6numberModernizrで使用すると、私が望んでいたことを正確に実行できることがわかりました。IEがES6Numberをサポートすることはないと思うので、この変更についてはあまり心配していません。これで、IEのバージョンとEdge / Chrome / Firefox / Opera / Safariのバージョンの違いがわかりました。

詳細はこちら:http//caniuse.com/#feat=es6-number

私はOperaMiniのフォールスネガについてはあまり気にしていないことに注意してください。あなたはそうかもしれません。


0

< !-- [if IE] > ハックを使用してグローバルjs変数を設定し、通常のjsコードでテストすることができます。少し醜いですが、私にとってはうまくいきました。


23
条件付きコメントは、Internet Explorer> = 10ではサポートされていません。
rudimenter 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.