【问题标题】:Detect Metro UI Version of IE检测 IE 的 Metro UI 版本
【发布时间】:2012-02-03 19:22:31
【问题描述】:

检测 User-Agent 为 UI 版本的 >=10 的最快方法是什么?

【问题讨论】:

  • 请阐明问题的整体思路以及您还想做什么。
  • 我认为他在问如何检测您的页面是作为 Metro 应用还是在 IE 10 中提供,因为它们都提供 JavaScript/HTML/CSS
  • 实际上,我认为 msec 是在询问您如何检测来自以“Metro 模式”运行的 IE10 和以“桌面模式”运行的 IE10 的 Web 请求(它们不一样)。我的答案如下。
  • 如前所述,我认为您无法具体确定 Metro UI。然而,使用一个小函数 here 很容易,您可以使用它来解析 IE 版本。下一步实际上是决定要检测哪些“特征”。检查Modernizr,它真的很好,干净又轻便。我发现它对现代 UI 开发非常有用。
  • 我的特定场景是创建一个等同于cubiq.org/add-to-home-screen 的Windows。显然需要根据 Metro 与桌面版本的浏览器更改 UI。如果你能识别出我可以做特征检测的东西来做出这种区分,你就会得到赏金:)

标签: metro internet-explorer javascript internet-explorer browser windows-8 microsoft-metro


【解决方案1】:

我认为没有办法确定请求是来自 Metro 版本的 IE10 还是来自常规桌面模式版本。 Metro IE 没有唯一的 HTTP 标头或用户代理字符串来识别它。

Internet Explorer 10 User Agent Strings On Windows 8 64bit

Metro IE10 是 64 位应用程序,因此您会在用户代理字符串中看到“Win64”。普通桌面 IE10 默认为 32 位,将显示“WOW64”。您可以基于此做出有根据的猜测,但您会错误地识别选择在桌面模式下运行 64 位版本 IE10 的任何人。从该图表中可以看出,用户代理字符串是相同的。 [编辑:如 cmets 中所述,这不适用于 32 位 PC。]

我明白为什么您可能想要检测 Metro IE,但通常不鼓励这种类型的“浏览器嗅探”,因为它非常麻烦且容易出错。如果可以的话,最好使用 Modernizr 之类的东西来测试您需要的某些浏览器功能。

【讨论】:

  • +1 - 有趣的是,IE10 有 Metro 版本和普通桌面版本。我的印象是 Metro 只是另一个呈现 Web 内容的界面。
  • 在消费者预览版中,是否有人将 64 位经典 IE10 的 UA 视为“Mozilla/5.0(兼容;MSIE 10.0;Windows NT 6.2;WOW64;Trident/6.0;.NET4.0E; .NET4.0C;媒体中心 PC 6.0)"?注意“WOW64”而不是“Win64”。
  • 对我来说问题是 IE10 Metro 不允许你测试一些区别于非 Metro 的特性,特别是 ActiveX 扩展永远不会被允许,所以你不应该打扰试图建立 UI 以提供安装它们。我写了一篇关于这个的博客文章。 blog.bertlamb.com/2012/06/07/…
  • 此解决方案不适用于桌面 UA 中也不存在“WOW64”和“Win64”的 32 位 PC
  • WOW64 和 Win64 都不存在于您实际上可能关心您正在运行的版本的设备上 - Surface 和其他 ARM 设备。
【解决方案2】:

我为此花了一些时间并想出了一个办法。我想到了 IE10 Metro 中缺少的东西,Metro UI 不支持仅记录的一件事。开发者工具。好吧,那些工具在 window 对象中有对象。其中之一是“__IE_DEVTOOLBAR_​​CONSOLE_COMMAND_LINE”。

如果你做类似的事情

if (window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE)
{
    // In IE 10 Standard UI
}
else
{
    // In IE 10 Metro UI
}

我已经在几个不同的环境中对其进行了测试,它似乎可以在大多数地方工作。我能想到的唯一问题是开发者工具是否在用户的浏览器上被某种方式禁用了。

【讨论】:

  • 您不应该检测 window.__IE_DEVTOOLBAR_​​CONSOLE_COMMAND_LINE。仅在打开 F12(开发人员工具栏)后才添加它,因此实际上它只是在测试 F12 是否已打开。您还将依赖 F12 的实现细节,因为它不是标准 API,因此可能会发生变化。
  • 仅供参考:在 IE11 中,window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE 似乎不再存在。取而代之的是 window.__BROWSERTOOLS_CONSOLEwindow.__BROWSERTOOLS_CONSOLE_BREAKMODE_INVOKERwindow.__BROWSERTOOLS_DOMEXPLORER_ADDED
【解决方案3】:

我测试了以下内容并且它可以工作,可以找到一个显示此内容的 jsfiddle here


这有点远,但似乎是一个明智的解决方案:

为什么不检查浏览器是否全屏1 并根据该调用全屏一个地铁。我的电脑上正在运行 Windows 8,所以我明天会尝试检查是否还有任何 GUI(我想我不记得了),如果有,你需要手动减去它们。诚然,这不是最漂亮的解决方案,但据我所知,不会有任何“漂亮”的解决方案,这可能被证明是一个非常可靠的 hack,因为 Metro IE 的 GUI 不能用任何工具栏更改或类似的软件(据我所知)。诚然,这可能会导致对桌面 IE 的错误识别,但即使这样也是合理的,因为全屏桌面 IE 仍会提供类似的体验。


1 给予一些东西:

if(window.innerWidth == screen.width && window.innerHeight == screen.height) {
  // metro
} else {
  // desktop
}

【讨论】:

  • 刚刚测试过,这确实识别地铁。尝试在 Metro 和桌面中打开 fiddle.jshell.net/JbGek/2/show/light
  • 嗯...你是对的,这似乎确实有效,不知道为什么它没有出现在我的测试页面上,可能是因为我在 IE 兼容模式下运行。
  • 在Firefox中,全屏的innerHeight比screen.height少一个像素,大概是因为最上面一行像素激活了工具栏
  • 有趣的是,在桌面和 Metro 中打开时,都报告“桌面”,F11 最大化桌面报告“Metro”,所以不幸的是它不可靠......它发生在超过 1 个显示器大小不一!
  • 这很奇怪,我当时用候选发布版对此进行了测试,它在小提琴中正确识别了两者。我想就地铁中的替代设置而言,可能需要进行一些额外的调整,但至少它让你比说什么都不可能(因为至少这在某些情况下确实有效)和桌面上全屏模式下的错误识别更远了我我的回答中已经提到是的。 (这是合理的,因为在这种情况下,您可能希望以任何一种方式显示类似 Metro 的界面)
【解决方案4】:

从它的声音来看,您正在寻求按照将站点固定到 Metro 内的开始屏幕的方式执行一些操作。为此,您可以使用 IE9 引入的代码检查是否可以固定站点,并且可以通过执行类似操作来完成...

function doChecks_Browser() {    
  // full pin abilities == can pin && Win7+    
  if (pinnedSiteDetection.hasFullPinAbilityBrowser)
}

关于here的更多信息。

来自 MSDN 上的 this post...

Windows 8 Release Preview 通过使用“开始”屏幕上的磁贴来实现固定网站。当用户单击固定网站的磁贴时,该网站会在 Windows Metro 风格 UI 环境中的 Windows Internet Explorer 10 Release Preview 中打开。

希望有帮助!

【讨论】:

  • Kinda... 我想通过视觉指示提示用户如何cubiq.org/add-to-home-screen 在iOS 上那样固定。此 UI 需要根据我使用的是 Desktop IE 还是 Metro IE 进行更改。
  • 嗯,好的。好吧,在这个 [链接] (msdn.microsoft.com/en-us/library/ie/gg491729(v=vs.85).aspx#drag) 中,它向您展示了如何做一个弹出窗口,告诉用户将站点图标拖到任务栏中。不确定等价物是什么,或者这是否适用于 Windows 8 上的 Metro,但值得一试。
【解决方案5】:

因此,似乎没有确定的测试来识别 Metro IE 与桌面 IE,但您似乎可以尝试使用一些不同的数据来假设它是 Metro。不幸的是,我发现的所有项目都无法通过其他设置来解释。换句话说,对于我发现的所有“功能”测试,Desktop IE 可以配置为诱使测试认为它是在 Metro 上运行的。

是否禁用 ActiveX(Metro 不允许任何 activex 内容,但桌面 IE 也可以将其设置为禁用):

function isActivexEnabled() {
    var supported = null;        
    try {
        supported = !!new ActiveXObject("htmlfile");
    } catch (e) {
        supported = false;
    }

    return supported;
}

用户代理字符串检查(Metro 将始终在 64 位模式下运行,但不会在 32 位机器上运行,并且桌面 IE 可以配置为在 64 位模式下运行,不确定这些选项中的任何一个会如何流行)

function isWin64() {
    return navigator.platform == "Win64";
}

全屏检查(Metro 将始终处于全屏模式,但桌面 IE 也可以以全屏模式运行,但这可以作为 Metro 模式的支持证据)

function isFullScreen() {
   return (window.innerWidth == screen.width && 
           window.innerHeight == screen.height);
}

简而言之,我认为您必须尝试检查一堆功能,然后猜测,没有确定的方法。或者您可以接受 MS 不希望您这样做,并对您想要使用的功能使用功能检测。

对于那些想要尝试提供 UI 以引用包含浏览器 UI(例如指示如何固定网页)的用户,请记住,其他 Metro 应用程序可以将 IE10 Metro 浏览器嵌入为控件,因此即使您可以将浏览器识别为 Metro 与桌面,UI 也可能不是您尝试引用它的地方,因此这最终可能是一个非常棘手的情况,要在 100% 的时间里正确。因此,要么不要尝试,要么您可以尝试其他检测技术并接受您可能会显示错误 UI 的用例。

【讨论】:

  • window.innerWidth == screen.width 不能用作 IE Metro 的测试。 1) 在桌面视图中,用户可以按 F11 进入全屏,此时屏幕值与 Metro 相同。 2) 因为 window.innerWidth != screen.width 使用快照/分屏视图时(如果 IE 向右对齐,则 window.screenX != 0)。
  • 同样,window.innerHeightwindow.innerWidth 都不能与屏幕高度/宽度进行比较,因为它们不是以物理像素为单位测量的。 innerHeight/innerWidth 值与窗口缩放成反比。
  • @robocat,同意 inerWidth 和 innerHeight 检查是不稳定的,但与其他检查一起使用它们可以潜在地增加 IE 处于 Metro 模式的信心,因为 MS 已经很友好地不为 Metro 模式提供真正的测试。这些检查本身并不意味着 IE 处于 Metro 模式,因为桌面 IE 可以配置为欺骗这些检查中的每一个,但桌面 IE 不太可能配置为欺骗所有检查。理想情况下,MS 将提供一种测试或识别 Metro 模式的真实方法。
  • document.documentElement.clientWidth == screen.width 更好地用于嗅探宽度,因为在 Metro 中,由于 Metro 中的错误,clientWidth 值不会随缩放而改变(在 Windows 8 上的 IE10.0.9200.16466 上测试)。 Desktop 中的值根据缩放(正确的行为)而变化。但是,如果用户在桌面 IE10 上按 F11,则嗅探将无法正常工作。试试看:jsbin.com/iqibik/2(在测试窗口/文档变量时,必须使用 jsbin,而不是 iframe 中的 jsfiddle!)
  • 我用这个方法成功了一段时间,但是发现包括全屏测试比较有问题。首先,它根本不适用于 IE11,因为 IE11 报告了不同的高度(我认为地址栏的高度现在包含在屏幕尺寸中,而在 IE10 中则没有)。但更重要的是,它在 IE 被捕捉时不起作用,这很常见。去掉全屏测试会降低检测的安全性,所以使用时要小心。
【解决方案6】:

METRO IE 从不支持 ActiveX 或任何插件对象。基于此,以下脚本已经过测试并且工作正常。

//---------------------------Metro IE check-------------------------
    var errorName = null;
    function isBrowserSupportPlugin() {
        var supported = null; 
        try {
            new ActiveXObject("");
        }
        catch (e) {
            // FF has ReferenceError here
            errorName = e.name; 
        }     
        try {
            supported = !!new ActiveXObject("htmlfile");
        } catch (e) {
            supported = false;
        }
        if(errorName != 'ReferenceError' && supported==false){
            supported = false;
        }else{
            supported =true;
        }
        return supported;
    }
//----------------------------------------------------------------   

【讨论】:

    【解决方案7】:

    感谢 John Rajakumar 和 Alexis Pigeon。我能够使用您的 Metro IE 检查作为基础,为 Metro 平板电脑 (MS Surface) 加载单独的 CSS 样式表。为了让我更加确定,我首先使用cssuseragent 来检测IE10,然后在最终的yepnope 测试中结合这两个测试。

    var IEmetrotest = ((cssua.userAgent.ie > 9) && (metrotest()));
    yepnope({
        test: IEmetrotest,
        yep : ['ie_metro.css']
        });
    

    在 Browserstack 中对其进行了测试,它按预期工作。 (我会加分给你,但还没有足够的分数。)

    // Minor revisions to isBrowserSupportPlugin() previously posted
    // Renamed function to metrotest() and inverted the returned value. 
    var errorName = null;
    function metrotest() {
        var supported = null; 
        try {
            new ActiveXObject("");
        }
        catch (e) {
            // FF has ReferenceError here
            errorName = e.name; 
        }     
        try {
            supported = !!new ActiveXObject("htmlfile");
        } catch (e) {
            supported = false;
        }
        if(errorName != 'ReferenceError' && supported==false){
            supported = false;
        }else{
            supported =true;
        }
        return !supported;
    }
    

    【讨论】:

      【解决方案8】:

      它尝试了下面的代码,它似乎可以工作。
      但是,如果用户对您使用 InternetOptions->CustomLevel->ScriptActivexControlsMarkedSafeForScripting=false,它不会捕获。如果用户这样做,代码就会认为它是 Metro/Modern。
      目前,通过检查操作系统、全屏和诸如此类的东西,我看不出有什么办法。

      isWinModern 检查 Metro/Modern。
      isWinDesktop 检查 Windows 作为桌面(=在这种情况下不是现代的)

      下面的代码不保证能正常工作。

          function isWin8Modern() {
              if (!!window.ActiveXObject) {
                  try {
                      !!new window.ActiveXObject('htmlfile');
                      return false;
                  } catch (exc) {
                      return true;
                  }
              } else {
                  return false;
              }
          }
      
          function isWinDesktop() {
              if (window.ActiveXObject) {
                  try {
                      new window.ActiveXObject('htmlfile');
                      return true;
                  } catch (exc) {
                      return false;
                  }
              } else {
                  return false;
              }
          }
      

      【讨论】:

        【解决方案9】:

        可靠的现代/地铁检测!

        我找到了一种检测 Modern 与 Desktop 的方法,您可以在此处尝试:http://jsbin.com/genac/2(使用 Chrome 或 Firefox 而不是 IE http://jsbin.com/genac/2/edit 进行编辑)。

        这似乎是一个相当可靠的检测,因为:

        • 即使捏合缩放也能正常工作
        • 即使两个窗口在 Modern(Metro) 上并排对齐,它也能正常工作
        • 即使使用 ctrl-+ 和 ctrl-- 缩放页面也能正常工作
        • 即使桌面全屏使用桌面上的 F11 键(自动隐藏任务栏)也能正常工作

        诀窍在于 Modern 上的页面滚动条不会使客户端窗口大小变小(它们显示在页面上方),但 Desktop 上的页面滚动条确实会影响客户端窗口大小(可用窗口大小更小)。

        主要的缺点是测试要求您在页面上有一个滚动条来嗅探差异。滚动条的相同差异是否发生在 iframe 或可自动滚动的 div 中?

        编辑:在使用此代码之前,我会测试浏览器是否为 IE11,因为 Windows 10 没有 Metro/Modern 并且 Edge 的行为略有不同。

        <!DOCTYPE html>
        <html>
        <head>
          <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
          <title>Metro width detector - robocat</title> 
          <script>
            function show() {
              var div = document.createElement('div');
              var s = [];
              s.push('IS METRO? ' + ((tester.offsetWidth == window.outerWidth) ? 'YES' : 'NO'));
              s.push('document.documentElement.clientWidth: ' + document.documentElement.clientWidth);
              s.push('document.documentElement.offsetWidth: ' + document.documentElement.offsetWidth);
              s.push('window.innerWidth: ' + window.innerWidth);
              s.push('window.outerWidth: ' + window.outerWidth);
              s.push('screen.width: ' + screen.width);
              s.push('screen.availWidth: ' + screen.availWidth);
              s.push('document.documentElement.getBoundingClientRect().width: ' + document.documentElement.getBoundingClientRect().width);
              s.push('tester.offsetWidth: ' + tester.offsetWidth);
              div.innerHTML = s.join('<br>');
              document.body.insertBefore(div, document.body.firstChild);
            }
            window.onresize = function() {
              show();
            }
          </script>
        </head>
          <body onload="show()" style="margin:0">
            <div id="tester" style="position:absolute;left:0;right:0;"></div>
          <div style="height:10000px;width:10px;background-color:blue;"></div>
        </body>
        </html>
        

        您可以使用以下方法查看页面/窗口尺寸:http://jsbin.com/AbimiQup/10(使用 Chrome 或 Firefox 而非 IE http://jsbin.com/AbimiQup/10/edit 进行编辑)

        PS:可能有一些方法可以从 runtimeStyle 嗅探 body 或 document.documentElement 的滚动条差异,因为可能使用了 -ms-overflow-style: -ms-autohiding-scrollbar(例如 document.documentElement.runtimeStyle.msOverflowStyle ) 但我找不到任何东西。

        PPS:其他答案中给出的 ActiveX 方法不是特别可靠(例如用户可以禁用),并且会导致 UI 丑陋,因为在 IE11 中它会在 url 旁边显示一个“ActiveX”图标。

        【讨论】:

        • 自我注释://MS 平板电脑检测:查看 ARM 的用户代理;和触摸;? Pro平板电脑怎么样? Windows Phone 的“Windows Phone”?注意“平板电脑”用于 IE8/IE9? // 64 位 IE9 与 32 位不同:“64 位 IE9 使用的是较旧、较慢的 JavaScript 引擎,而 32 位 IE9 使用的是较新、更高效的 Chakra JIT。Internet Explorer 9 64-在 JavaScript 性能方面,bit 绝对是一只狗。” // RELIABLE METRO VERSUS DESKTOP TEST?!: 身体上的滚动条宽度为零 - 外部宽度减去内部宽度。在 IE10 Metro 滚动条不透明地覆盖在顶部并且宽度为零。
        【解决方案10】:

        这是一个一致的方法,没有 ActiveX 检查依赖项,在 IE10 和 IE11 中进行了测试特别是

        if (window.screenY === 0 && (window.innerHeight+1) !== window.outerHeight){ //IE metro/modern UI }
        

        第一条规则检测 IE 的全屏或现代视图(在 IEMobile 上可能是也可能是真的)。 最大化模式在历史上总是与正或负 screenX 和 screenY 相关联。

        最后一条规则排除了 [全屏/F11] 模式,由于某种原因,在 IE10/Win8 和 IE11/Win8.1 上测试时,outerHeightinnerHeight 之间不断显示 1px 的差异

        PS:我自愿不声明window.screenX === 0。仅使用 screenY 以在捕捉模式下覆盖 Modern/Metro,窗口上下文捕捉到右侧(即 screenX !== 0)。

        【讨论】:

        • 这太棒了。我已经在 IE 10+11、metro+desktop+fullscreen 上对此进行了广泛的测试。我要补充一点,您需要检查您是否正在运行 IE(可能使用 UA 字符串),因为其他浏览器在某些情况下可以通过这两项测试(例如 Chrome 全屏)。
        • 似乎也可以在快照模式下使用,并且可以在任何缩放级别下使用!
        • @aaaidan 我知道!我进行了广泛的测试:) 确实 IE 检测是先决条件。鉴于 IE 10、11 和即将推出的 IE12 之间的用户代理发生了根本性的变化,此时最好的选择可能是 !!window.StyleMedia。我最终会相应地更新我的答案。
        【解决方案11】:
        var _ua = window.navigator.userAgent;
        var isIDevice = (/iphone|ipod|ipad/i).test(_ua);
        var isMobileChrome = (_ua.indexOf('Android') > -1 && (/Chrome\/[.0-9]*/).test(_ua) && _ua.indexOf("Version") == -1);
        var isMobileIE = _ua.indexOf('Windows Phone') > -1;
        function isActivexEnabled()
        {
            var supported = null;        
            try
            {
                supported = !!new ActiveXObject("htmlfile");
            } 
            catch (e) 
            {
                supported = false;
            }
            return supported;
        }
        if (!isIDevice && !isMobileChrome && !isMobileIE &&  _ua.toLowerCase().indexOf("wow") == -1 && !isActivexEnabled())
        { 
            //IE Metro UI
        }
        

        这项工作适合我..

        【讨论】:

          猜你喜欢
          • 2011-11-06
          • 1970-01-01
          • 2011-03-14
          • 2011-09-11
          • 2012-06-13
          • 2011-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多