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


84

我想使用Modernizr JS库检测某些浏览器属性,以确定要显示或不显示哪些内容。

我有一个名为Pano2VR的应用程序,它可以同时输出HTML5和SWF。我需要用于iOS设备用户的HTML5。

但是,IE根本不呈现此“ HTML5”输出。看来它们的输出使用CSS3 3D转换和WebGL,IE9中显然不支持一种或多种。

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

所有这些导致我如何使用Modernizr来仅检测IE或不检测IE?还是检测CSS 3d转换?

还是有其他方法可以做到这一点?

Answers:


1

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

因此,我启动了许多浏览器,并直接检查了Modernizer。我添加了一些我肯定需要的功能,然后添加了“ inputtypes.color”,因为它似乎涵盖了我关心的所有主要浏览器:Chrome,Firefox,Opera,Edge ...和NOT 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;
}

这就是“ 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
要记住的一件事:UA字符串是完全可由用户配置的。因此,检查UA字符串不是检查浏览器的一致方法。 developer.mozilla.org/zh-CN/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 2013年

51
是的,但是有多少百分比的用户使用已修改/欺骗/错误的UA字符串浏览网络?您想花费多少工程时间来确保少数人在您的站点上获得最佳体验?通过UA字符串进行浏览器嗅探是一种实用且理智的方法。
杰德·理查兹

17
@Wintamute,完全同意。厌倦了“特征检测是邪恶的”这类演讲。我们在做工程,而不是追求艺术
Philip007

9
通常的假设是,如果有人修改了UA字符串,则他们知道自己在做什么,并且可以处理后果。实际上,这正是UA字符串存在的目的-向服务器声明浏览器版本。如果客户想撒谎,那就好了!当然,在未经用户同意的情况下更改字符串的可能性很小,但实际上这不是真正的问题-嘿,我们也应该喂饱用户并擦他们的背吗?
Rolf

20

通过检查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 */
}

另外,您可以将Modernizr与简单的JavaScript方法结合使用,如下所示:

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

请记住,IE / Edge可能有朝一日支持SMIL,但目前尚无计划。

作为参考,这是位于caniuse.comSMIL兼容性图表的链接


最佳答案imo。如此简单
Batman

2
虽然这确实有效,但目前仍有效。特征检测和Modernizr的全部目的是您不必担心明天会发生什么。如果Edge在明天通过smil支持进行更新,则您的代码将不再起作用,您甚至可能不知道。
杰森


1
这看起来很简单,但显然Edge现在支持SMIL
杰里米·卡尔森

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

如果您已经初始化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;
}());

注意:仅在IE9(含)以下才支持IE条件注释。从IE10开始,Microsoft鼓励使用功能检测而不是浏览器检测。


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

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

||当然,不要从字面上看。


我个人总是尝试基于特征的检测而不是浏览器检测
Chris

@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

好吧,在对该主题进行了更多研究之后,我最终使用了以下解决方案来定位IE 10+。因为IE10&11是唯一支持-ms-high-contrast媒体查询的浏览器,所以这是不带任何JS的好选择:

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

完美运作。



1

我需要检测IE和大多数其他内容,并且我不想依赖UA字符串。我发现es6number与Modernizr一起使用完全可以实现我想要的功能。我对此变化没有太大的担心,因为我不希望IE支持ES6 Number。所以现在我知道IE的任何版本与Edge / Chrome / Firefox / Opera / Safari之间的区别。

此处有更多详细信息:http : //caniuse.com/#feat=es6-number

请注意,我不太担心Opera Mini的误报功能。你可能是。


0

您可以使用< !-- [if IE] > hack设置一个全局js变量,然后在常规js代码中对其进行测试。有点难看,但对我来说效果很好。


23
Internet Explorer> = 10中不再支持条件注释。
rudimenter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.