使用Modernizr检测IE的正确方法?

Ste*_*eve 82 html5 cross-browser modernizr

这可能是一个愚蠢的问题,但我想使用Modernizr JS库来检测某些浏览器属性,以确定要显示或不显示的内容.

我有一个名为Pano2VR的应用程序,它输出HTML5和SWF.我需要HTML5 for iOS设备用户.

但是,IE根本不会呈现此"HTML5"输出.似乎他们的输出使用CSS3 3D变换和WebGL,IE9中显然不支持一个或多个.

因此,对于那些用户,我需要显示Flash版本.我打算使用IFRAME并通过Modernizr脚本传递SRC或document.write出正确的IFRAME代码,具体取决于浏览器.

所有这些都导致我如何使用Modernizr来检测IE或IE?或者检测CSS 3d变换?

或者还有另一种方法吗?

Cod*_*ely 190

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>");
Run Code Online (Sandbox Code Playgroud)

然后,您只需检查:

BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是有多少百分比的用户使用修改/欺骗/错误的UA字符串浏览网页?您希望花多少工程时间来确保极少数人能够在您的网站上获得最佳体验?浏览器通过UA字符串嗅探是一种实用且理智的方法. (49认同)
  • @Wintamute,不能同意.厌倦了"特征检测是邪恶的"讲座.我们正在做工程,而不是追求艺术 (16认同)
  • 一般的假设是,如果某人修改了他们的UA字符串,那么他们就知道他们正在做什么,他们可以处理后果.实际上,这正是UA字符串的存在 - 向服务器声明浏览器版本.如果客户想要撒谎,那么,这就是生活!当然,在未经用户同意的情况下更换字符串的可能性很小,但在实践中这并不是真正的问题 - 嘿,我们是否应该为用户提供食物并揉搓他们? (7认同)
  • 谢谢.我终于追查到问题是他们的文件需要webgl支持.因此,我可以使用Modernizer来测试它并执行另一个代码块的document.write.但这是浏览器检测的绝佳解决方案.再次感谢. (2认同)
  • 需要记住的一点是:UA字符串完全是用户可配置的.因此,检查UA字符串并不是检查浏览器的一致方法.https://developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent在"注释"部分:`基于检测用户代理字符串的浏览器标识不可靠,不建议用户代理字符串是用户可配置的 (2认同)

jac*_*arm 19

通过检查SVG SMIL动画支持,您可以使用Modernizr来检测IE或不是IE .

如果您在Modernizr设置中包含了SMIL特征检测,则可以使用简单的CSS方法,并将Modernizr应用于.html元素的.no-smil类作为目标:

html.no-smil {
  /* IE/Edge specific styles go here - hide HTML5 content and show Flash content */
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用Modernizr使用简单的JavaScript方法,如下所示:

if ( Modernizr.smil ) {
  /* set HTML5 content */
} else {
  /* set IE/Edge/Flash content */
}
Run Code Online (Sandbox Code Playgroud)

请记住,IE/Edge可能有一天会支持SMIL,但目前还没有计划这样做.

作为参考,这里是caniuse.com上SMIL兼容性图表的链接.

  • 虽然这确实有效,但它现在有效.功能检测和Modernizr的重点在于您不必担心明天会发生什么.如果Edge明天更新并获得smil支持,那么您的代码将不再有效,您可能甚至不知道它. (2认同)

ion*_*ono 12

检测CSS 3D变换

Modernizr 可以检测CSS 3D变换,是的.Modernizr.csstransforms3d如果浏览器支持它们,真实性将告诉您.

上面的链接允许您选择要包含在Modernizr构建中的测试,并且您可以在那里找到您要查找的选项.


具体检测IE

或者,当user356990回答时,如果您单独搜索IE和IE,则可以使用条件注释.您可以使用HTML5 Boilerplate的<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]-->
Run Code Online (Sandbox Code Playgroud)

如果你已经初始化了jQuery,你可以查看$('html').hasClass('lt-ie9').如果你需要检查你所在的IE版本,以便有条件地加载jQuery 1.x或2.x,你可以这样做:

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;
}());
Run Code Online (Sandbox Code Playgroud)

NB IE条件注释仅支持包含IE9的IE9.从IE10开始,Microsoft鼓励使用功能检测而不是浏览器检测.


无论您选择哪种方法,都可以进行测试

if ( myChecks.ltIE9 || Modernizr.csstransforms3d ){
    // iframe or flash fallback
} 
Run Code Online (Sandbox Code Playgroud)

||当然,不要从字面上理解.


Pet*_*e B 9

如果您正在寻找一个JS版本(使用特征检测和UA嗅探的组合)来处理html5样板:

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


Eth*_*man 1

我同意我们应该测试功能,但是很难找到一个简单的答案来回答“‘现代浏览器’支持哪些功能而不是‘旧浏览器’?”

所以我启动了一堆浏览器并直接检查了 Modernizer。我添加了一些我确实需要的功能,然后添加了“inputtypes.color”,因为这似乎涵盖了我关心的所有主要浏览器:Chrome、Firefox、Opera、Edge...而不是 IE11。现在我可以温和地建议用户使用 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;
}
Run Code Online (Sandbox Code Playgroud)

这是“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;
}
Run Code Online (Sandbox Code Playgroud)