-
-
Save cowboy/542301 to your computer and use it in GitHub Desktop.
// ---------------------------------------------------------- | |
// A short snippet for detecting versions of IE in JavaScript | |
// without resorting to user-agent sniffing | |
// ---------------------------------------------------------- | |
// If you're not in IE (or IE version is less than 6) then: | |
// ie === 0 | |
// If you're in IE (>=6) then you can determine which version: | |
// ie === 7; // IE7 | |
// Thus, to detect IE: | |
// if (ie) {} | |
// And to detect the version (after IE has been detected): | |
// ie === 6 // IE6 | |
// ie > 7 // IE8, IE9 ... | |
// ie < 9 // Anything less than IE9 | |
// ---------------------------------------------------------- | |
// GOAL: the smallest possible minified size (without using conditional compilation) | |
// While using `with` makes automatic minification difficult (if not impossible) | |
// due to the fact that the minifier doesn't necessarily know which identifiers | |
// reference properties of the specified object versus variables in the scope | |
// chain, I'm using it here and minifying manually. | |
with ( document.createElement("b") ) | |
// No curly braces needed for the `with` because only the following `for` | |
// loop (a single statement) needs to execute inside the `with`. | |
for ( | |
// Initialize the for loop by declaring the `ie` var, setting its value to | |
// -1 (which will get incremented at least once). | |
var ie = -1; | |
// Increment `ie` and update the innerHTML of the element accordingly. If | |
// the browser is IE with a version greater than `ie`, "1" will be written | |
// into the element. | |
innerHTML = "<!--[if gt IE " + ++ie + "]>1<![endif]-->" | |
// Unfortunately, because testing innerHTML at the time of assignment is | |
// inadequate, a separate expression must be used. The comma operator allows | |
// both the preceding and the following expression to be evaluated, with | |
// only the last expressions's result affecting the for loop's condition. | |
, | |
// If non-IE (or a lower version IE), the innerHTML will be an empty string, | |
// which gets coerced to 0 (falsy) by the + operator. Otherwise, it will be | |
// "1" which gets coerced to 1 (truthy). Basically, as long as the innerHTML | |
// is "1", continue looping. | |
+innerHTML; | |
// Because `ie` is incremented in the condition, no increment expression is | |
// needed here! | |
); | |
// (It should go without saying that if the var was named `i` instead of `ie`, | |
// a few more bytes could be saved, but I'm saying it anyways, because that's | |
// how I roll) | |
// Minified (111 chars): | |
with(document.createElement("b"))for(var ie=-1;innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",+innerHTML;); | |
// Version without `with` in case that's how you roll (112 chars): | |
for(var ie=-1,b=document.createElement("b");b.innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",+b.innerHTML;); |
I'm not really down with the global var solution, as it would make this unsuitable for inclusion in production code.. but your coercing +innerHTML
was awesome, so I added it into my gist. Sweet!
Yah, I got a little carried away there.
Now we wait for @jdalton to find the one use-case where it will break. haha. :o)
+1
Even better, you don't need explicit typecasting at all, just innerHTML
will do the trick, too. ;-)
Marcel, have you actually even tried that cross-browser?
Yes, at least in FF4, IE8, IE8-acting-as-IE7, Chromium 10.
with(document.body)for(var ie=0;innerHTML="<!--[if gt IE "+ie+"]>1<![endif]-->",+innerHTML;ie++);
97 chars. Tested in IE 6-8, FF and Chrome, needs to be above body tag.
Also, firefox 3.6 needs the +innerHTML, can't use just "innerHTML"
http://jsfiddle.net/kflorence/cu9Pw/ -- 97 chars
Ah, I think I found out why. If you put that code in a script block before your body tag it will be executed before the body has content it seems... example
One very small correction in your code comments.
// If non-IE (or a lower version IE), the innerHTML will be an empty string,
// which gets coerced to 0 (falsy) by the + operator.
While it is the case for IE that innerHTML
will be an empty string, for non-IE browsers you'll get the full HTML code comment:
<!--[if gt IE 0]>1<![endif]-->
...which is coerced to NaN
by the unary +
operator.
Of course the outcome is the same, as both 0
and NaN
are "falsey".
(ie <= 7) is causing an error in IE8:
'Undefined' is null or not an object.
Such a sweet, sweet, slender piece of code. So.... what's the absolute smallest way to add detection for IE10 without conditional comments (not supported) or UA-sniffing? I think
document.body.style.msFlex
is the shortest :)
\o/ for Code Golf! 108 chars now:
with(ie=-1,document.createElement("b"))while(innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",+innerHTML);
p.s., this last one doesn't care about local scope; it will take up residence in your
window
. It will clobberwindow.ie
if it already existed.