What\'s the fastest method, to detect User-Agent as metro UI version of internet-explorer >=10
?
Here is a consistent method, with no ActiveX check dependency, as tested in IE10 and IE11 specifically.
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). Maximized mode being historically always associated with positive or negative screenX and 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
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).
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..
I tested the following and it works, a jsfiddle showing this can be found here.
This is a bit of long shot, but seems quite a sensible solution:
Why not check whether the browser is full screen1 and 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 Giving something along the lines of:
if(window.innerWidth == screen.width && window.innerHeight == screen.height) {
// metro
} else {
// desktop
}
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 cssuseragent to detect IE10 first, and then combined both tests in a final yepnope test.
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.)
// 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;
}
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.
isWinModern checks for Metro/Modern.
isWinDesktop checks for Windows as Desktop (=non modern in this case)
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;
}
}
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.
Is ActiveX disabled (Metro doesn't allow any activex content, but desktop IE can have it set to disabled as well):
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)
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)
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.
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.