javascript 检测IE的Metro UI版本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8751479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect Metro UI Version of IE
提问by mate64
What's the fastest method, to detect User-Agent as metroUI version of internet-explorer>=10
?
将 User-Agent 检测为Internet-explorer 的MetroUI 版本的最快方法是什么?>=10
采纳答案by Bert Lamb
So, there doesn't appear to be a definitive test to identify Metro IE vs Desktop IE, but there does seem to be a few different pieces of data you can attempt to use to assume that it is Metro. Unfortunately, none of the items I have found can't be explained away by other settings. In other words, for all the "feature" tests I have found, Desktop IE could be configured in a way to trick the tests into thinking it was running on Metro.
因此,似乎没有确定 Metro IE 与桌面 IE 的明确测试,但似乎确实有一些不同的数据可供您尝试使用以假设它是 Metro。不幸的是,我发现的所有项目都无法通过其他设置来解释。换句话说,对于我发现的所有“功能”测试,Desktop IE 可以通过某种方式进行配置,以欺骗测试认为它在 Metro 上运行。
Is ActiveX disabled (Metro doesn't allow any activex content, but desktop IE can have it set to disabled as well):
是否禁用了 ActiveX(Metro 不允许任何 ActiveX 内容,但桌面 IE 也可以将其设置为禁用):
function isActivexEnabled() {
var supported = null;
try {
supported = !!new ActiveXObject("htmlfile");
} catch (e) {
supported = false;
}
return supported;
}
User Agent string check (Metro will always run in 64bit mode, but won't on a 32bit machine, and Desktop IE can be configured to run in 64bit mode as well not sure how popular either of those options will be)
用户代理字符串检查(Metro 将始终以 64 位模式运行,但不会在 32 位机器上运行,并且桌面 IE 可以配置为以 64 位模式运行,但不确定这两个选项中的任何一个的流行程度)
function isWin64() {
return navigator.platform == "Win64";
}
Full screen check (Metro will always be in full screen mode, however Desktop IE can also run in full screen mode, but this could be used as supporting evidence of Metro mode)
全屏检查(Metro 将始终处于全屏模式,但桌面 IE 也可以在全屏模式下运行,但这可以作为 Metro 模式的支持证据)
function isFullScreen() {
return (window.innerWidth == screen.width &&
window.innerHeight == screen.height);
}
In short, I think you have to try to check a bunch of features, and then guess, there is no definitive way. Or you could just accept that MS doesn't want you to do this, and use feature detection for the features you want to use.
总之,我认为你必须尝试检查一堆功能,然后猜测,没有确定的方法。或者您可以接受 MS 不希望您这样做,并对您要使用的功能使用特征检测。
For those that want to try to provide UI to refer to the containing browser UI (to indicate how to Pin the web page for example), keep in mind that other Metro apps can embed the IE10 Metro browser as a control, so even if you could identify the browser as Metro vs desktop, the UI might not be where you'd attempt to refer to it, so this can end up being a pretty tricky situation to get right 100% of the time. So either, don't try, or you could attempt the other detection techniques and accept that there are use cases that you could be displaying the wrong UI.
对于那些想要尝试提供 UI 以引用包含的浏览器 UI(例如指示如何固定网页)的人,请记住,其他 Metro 应用程序可以将 IE10 Metro 浏览器作为控件嵌入,因此即使您可以将浏览器识别为 Metro 与桌面,UI 可能不是您尝试引用它的地方,因此这最终会成为一个非常棘手的情况,以 100% 的时间正确。因此,要么不要尝试,要么尝试其他检测技术并接受可能会显示错误 UI 的用例。
回答by Kurt Schindler
I don't believe there is a way to determine if a request is coming from the Metro version of IE10 versus the regular desktop mode version. Metro IE has no unique HTTP headers or user-agent string to identify it by.
我不相信有一种方法可以确定请求是来自 IE10 的 Metro 版本还是来自常规桌面模式的版本。Metro IE 没有唯一的 HTTP 标头或用户代理字符串来识别它。
Internet Explorer 10 User Agent Strings On Windows 8 64bit
Windows 8 64 位上的 Internet Explorer 10 用户代理字符串
Metro IE10 is a 64-bit application, so you'll see "Win64" in the user-agent string. Regular desktop IE10, by default, is 32-bit and will show "WOW64". You could sort-of make an educated guess based on this, but you would falsely identify anyone who chose to run the 64-bit version of IE10 in desktop mode. As you can see from that chart, the user-agent strings are identical. [edit: as noted in the comments, this won't work for 32-bit PCs.]
Metro IE10 是 64 位应用程序,因此您将在用户代理字符串中看到“Win64”。默认情况下,普通桌面 IE10 为 32 位,将显示“WOW64”。您可以基于此做出有根据的猜测,但您会错误地识别出选择在桌面模式下运行 64 位版本的 IE10 的任何人。从该图表中可以看出,用户代理字符串是相同的。[编辑:如评论中所述,这不适用于 32 位 PC。]
I could see why you may want to detect Metro IE, but this type of "browser sniffing" is generally discouraged because it's so cumbersome and error-prone. It would be best to feature test for certain browser functionality that you require using something like Modernizr, if you can.
我可以理解为什么您可能想要检测 Metro IE,但通常不鼓励这种类型的“浏览器嗅探”,因为它非常麻烦且容易出错。如果可以的话,最好使用Modernizr 之类的东西对您需要的某些浏览器功能进行特性测试。
回答by Thor
Thanks John Rajakumar and Alexis Pigeon. I was able to use your Metro IE check as the basis to load a separate CSS style sheet for Metro tablets (MS Surface). To add a bit more certainty in my mind, I used cssuseragentto detect IE10 first, and then combined both tests in a final yepnopetest.
感谢 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']
});
Tested it in Browserstack and it's working as expected. (I would have up-ticked you, but don't have enough points yet.)
在 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;
}
回答by John Rajakumar
METRO IE never supports ActiveX or any plugin objects. Based on that the following script is tested & working fine.
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;
}
//----------------------------------------------------------------
回答by robocat
Reliable Modern/Metro detection!
可靠的现代/地铁检测!
I have found a way to detect Modern versus Desktop which you can try here: http://jsbin.com/genac/2(edit using Chrome or Firefox not IE http://jsbin.com/genac/2/edit).
我找到了一种检测现代与桌面的方法,您可以在这里尝试:http: //jsbin.com/genac/2(使用 Chrome 或 Firefox 进行编辑,而不是 IE http://jsbin.com/genac/2/edit)。
It seems to be a fairly robust detection because:
这似乎是一个相当强大的检测,因为:
- it works even if pinch-zoomed
- it works even if two windows snapped side by side on Modern(Metro)
- it works even if page zoomed using ctrl-+ and ctrl--
- it works even if desktop is fullscreen using F11 key on Desktop (autohiding taskbar)
- 即使缩放它也能工作
- 即使两个窗户在现代(地铁)上并排咬合,它也能工作
- 即使使用 ctrl-+ 和 ctrl-- 缩放页面,它也能工作
- 即使桌面全屏使用桌面上的 F11 键它也能工作(自动隐藏任务栏)
The trick is that the page scrollbars on Modern do not make the client window size smaller (they appear above the page), but the page scrollbars on Desktop do affect client window size (usable window size is smaller).
诀窍是 Modern 上的页面滚动条不会使客户端窗口尺寸变小(它们出现在页面上方),但桌面上的页面滚动条确实会影响客户端窗口尺寸(可用窗口尺寸更小)。
The main downside is that the test requires that you have a scrollbar on the page to sniff the difference. Does the same difference in scrollbars happen in an iframe or autoscrollable div?
主要的缺点是该测试要求您在页面上有一个滚动条来嗅探差异。在 iframe 或自动滚动的 div 中是否发生了滚动条的相同差异?
Edit: I would test that the browser is IE11 before using this code, because Windows 10 doesn't have Metro/Modern and Edge acts slightly differently.
编辑:在使用此代码之前,我会测试浏览器是否为 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>
You can look at page/window dimensions using: http://jsbin.com/AbimiQup/10(edit using Chrome or Firefox not IE http://jsbin.com/AbimiQup/10/edit)
您可以使用以下方法查看页面/窗口尺寸:http: //jsbin.com/AbimiQup/10(使用 Chrome 或 Firefox 进行编辑,而不是 IE http://jsbin.com/AbimiQup/10/edit)
PS: There might be some way to sniff the scrollbar difference from the runtimeStyle for body or document.documentElement because maybe -ms-overflow-style: -ms-autohiding-scrollbar is used (e.g. document.documentElement.runtimeStyle.msOverflowStyle) but I couldn't find anything.
PS:可能有一些方法可以从 body 或 document.documentElement 的 runtimeStyle 中嗅探滚动条的差异,因为可能使用了 -ms-overflow-style: -ms-autohiding-scrollbar(例如 document.documentElement.runtimeStyle.msOverflowStyle)但我找不到任何东西。
PPS: The ActiveX method given in other answers is not particularly reliable (e.g. users can disable) and it causes UI uglyness because in IE11 it shows a "ActiveX" icon next to the url.
PPS:其他答案中给出的 ActiveX 方法不是特别可靠(例如,用户可以禁用)并且它会导致 UI 丑陋,因为在 IE11 中它在 url 旁边显示一个“ActiveX”图标。
回答by hexalys
Here is a consistent method, with no ActiveX check dependency, as tested in IE10 and IE11 specifically.
这是一种一致的方法,没有 ActiveX 检查依赖项,具体在 IE10 和 IE11 中进行了测试。
if (window.screenY === 0 && (window.innerHeight+1) !== window.outerHeight){ //IE metro/modern UI }
The first rule detect IE's full screen or modern view (which may or can also be true on IEMobile). Maximizedmode being historically always associated with positive or negative screenX and screenY.
第一条规则检测 IE 的全屏或现代视图(在 IEMobile 上可能或也可能适用)。 最大化模式历来总是与正面或负面 screenX 和 screenY 相关联。
And the last rule excludes [Full screen/F11] mode, which for some reason constantly shows a 1px discrepancy between outerHeight
and innerHeight
as tested on IE10/Win8 and IE11/Win8.1
和最后一个规则排除[全屏/ F11]模式下,由于某种原因不断显示之间1px的差异outerHeight
和innerHeight
作为IE10 / Win8的和IE11 / Win8.1测试
PS: I voluntarily do not declare window.screenX === 0
. Only use screenY
in order to cover Modern/Metro in snap-mode with a window context snapped to the right (i.e. screenX !== 0).
PS:我自愿不申报window.screenX === 0
。仅用于screenY
在捕捉模式下以捕捉到右侧的窗口上下文(即 screenX !== 0)覆盖 Modern/Metro。
回答by DeltaFoX
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
}
This Work For Me..
这对我有用..
回答by LosManos
It tried out the code below and it seems to work.
It doesn't catch if the user goes InternetOptions->CustomLevel->ScriptActivexControlsMarkedSafeForScripting=false on you though. If the user does this the code believes it's a Metro/Modern.
Presently I see no way around this by checking OS, FullScreen and whatnot.
它尝试了下面的代码,它似乎有效。
但是,如果用户对您使用 InternetOptions->CustomLevel->ScriptActivexControlsMarkedSafeForScripting=false,它不会被捕获。如果用户这样做,则代码认为它是 Metro/Modern。
目前,我无法通过检查操作系统、全屏等来解决这个问题。
isWinModern checks for Metro/Modern.
isWinDesktop checks for Windows as Desktop (=non modern in this case)
isWinModern 检查 Metro/Modern。
isWinDesktop 检查 Windows 作为桌面(在这种情况下=非现代)
The code below is not guaranteed to work.
下面的代码不能保证工作。
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;
}
}
回答by David Mulder
I tested the following and it works, a jsfiddle showing this can be found here.
我测试了以下内容并且它有效,可以在此处找到显示此内容的 jsfiddle 。
This is a bit of long shot, but seems quite a sensible solution:
这有点远,但似乎是一个非常明智的解决方案:
Why not check whether the browser is full screen1and depending on that call the fullscreen one metro. I have windows 8 running on my computer at work, so I will try to check tomorrow whether there are any GUI's still around (don't think I remember any) and if so, you would need to manually subtract them. True, it's not the most beautiful solution, but as far as I know there won't be any 'beautiful' solution and this could prove to be a pretty solid hack, as the GUI of metro IE can't be changed with any toolbars or similar software (as far as I know). True, it could lead to a misidentification of the desktop IE, but even that is within reason, as a fullscreen desktop IE will still give a similar experience.
为什么不检查浏览器是否是全屏1并根据它调用全屏 1 地铁。我在工作时在我的计算机上运行 Windows 8,所以我明天会尝试检查是否还有任何 GUI(我不记得了),如果有,您需要手动减去它们。确实,这不是最漂亮的解决方案,但据我所知不会有任何“漂亮”的解决方案,这可能被证明是一个非常可靠的黑客,因为 Metro IE 的 GUI 不能用任何工具栏更改或类似的软件(据我所知)。诚然,这可能会导致对桌面 IE 的错误识别,但即便如此也在情理之中,因为全屏桌面 IE 仍会提供类似的体验。
1Giving something along the lines of:
1给予一些东西:
if(window.innerWidth == screen.width && window.innerHeight == screen.height) {
// metro
} else {
// desktop
}
回答by tcmorris
By the sounds of it you are looking to do something along the lines of Pinning a site to the start screen within Metro. To do that you can check if a site can be pinned by using this code that was brought in with IE9 and can be done by doing something like this...
根据它的声音,您正在寻找沿着将站点固定到 Metro 中的开始屏幕的路线做一些事情。为此,您可以使用 IE9 中引入的此代码检查是否可以固定站点,并且可以通过执行以下操作来完成...
function doChecks_Browser() {
// full pin abilities == can pin && Win7+
if (pinnedSiteDetection.hasFullPinAbilityBrowser)
}
More info on that here.
更多信息在这里。
From this this poston MSDN...
从这篇MSDN 上的这篇文章...
Windows 8 Release Preview implements pinned sites by using tiles on the Start screen. When a user clicks the tile of a pinned site, the site opens in Windows Internet Explorer 10 Release Preview in the Windows Metro style UI environment.
Windows 8 Release Preview 通过在“开始”屏幕上使用磁贴来实现固定站点。当用户单击固定站点的磁贴时,该站点将在 Windows Metro 风格 UI 环境中的 Windows Internet Explorer 10 Release Preview 中打开。
Hope that helps!
希望有帮助!