-
-
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;); |
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 :)
Even better, you don't need explicit typecasting at all, just
innerHTMLwill do the trick, too. ;-)