Create a gist now

Instantly share code, notes, and snippets.

Embed
Very small IE detect (aka type coersion ftw)
// ----------------------------------------------------------
// 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;);
@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Aug 21, 2010

My previous version was still quite small at 142 chars, because it used a closure, but the closure is really unnecessary in this case. View the live test page to see it in action. Also notice that ie === 0 in non-IE browsers.

Owner

cowboy commented Aug 21, 2010

My previous version was still quite small at 142 chars, because it used a closure, but the closure is really unnecessary in this case. View the live test page to see it in action. Also notice that ie === 0 in non-IE browsers.

@marcelkorpel

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

marcelkorpel Aug 22, 2010

Why do you use the unary plus operator in var ie = id > 5 ? +id : 0? It does nothing and adds a character to your minified version.

And why did you change the minimal IE version to detect to 6? IE 5 also supports conditional comments.

Why do you use the unary plus operator in var ie = id > 5 ? +id : 0? It does nothing and adds a character to your minified version.

And why did you change the minimal IE version to detect to 6? IE 5 also supports conditional comments.

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Aug 23, 2010

Marcel, I use + to cast id, which is a string, to a number. I changed the comment to more accurately reflect that this code detects a minimum version of IE6 (I don't really care about IE5 support).

Owner

cowboy commented Aug 23, 2010

Marcel, I use + to cast id, which is a string, to a number. I changed the comment to more accurately reflect that this code detects a minimum version of IE6 (I don't really care about IE5 support).

@marcelkorpel

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

marcelkorpel Aug 23, 2010

Ah, I didn't know about the side-effect of typecasting of +. Indeed, according to the ECMAScript specification, + converts ToNumber(GetValue(expr)).

The only thing is, id is never changed into a string; only the innerHTML is.

Ah, I didn't know about the side-effect of typecasting of +. Indeed, according to the ECMAScript specification, + converts ToNumber(GetValue(expr)).

The only thing is, id is never changed into a string; only the innerHTML is.

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Aug 23, 2010

In Chrome console, if you enter var b=document.createElement("b"); b.id=1; b.id, you get "1" (string).

Owner

cowboy commented Aug 23, 2010

In Chrome console, if you enter var b=document.createElement("b"); b.id=1; b.id, you get "1" (string).

@marcelkorpel

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

marcelkorpel Aug 23, 2010

Of course, I didn't think of the impact of the with statement.

Of course, I didn't think of the impact of the with statement.

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Aug 23, 2010

Yeah, that's how I can get away with not needing a closure or temp var!

Owner

cowboy commented Aug 23, 2010

Yeah, that's how I can get away with not needing a closure or temp var!

@balupton

This comment has been minimized.

Show comment
Hide comment
@balupton

balupton Jan 23, 2011

Great stuff, what's the license? Or is it so small, that it would fall under public domain?...

... also, how come var ie is inside the with, and id is missing var?...

Great stuff, what's the license? Or is it so small, that it would fall under public domain?...

... also, how come var ie is inside the with, and id is missing var?...

@kflorence

This comment has been minimized.

Show comment
Hide comment
@kflorence

kflorence Feb 8, 2011

I believe he is accessing the id as a property of the element (element.id), so it does not need a var declaration.

I believe he is accessing the id as a property of the element (element.id), so it does not need a var declaration.

@davidmurdoch

This comment has been minimized.

Show comment
Hide comment
@davidmurdoch

davidmurdoch Apr 8, 2011

121 chars: with(document.createElement("b")){for(id=-1;innerHTML="<!--[if gt IE "+ ++id +"]>1<![endif]-->",innerHTML>0;);var ie=+id}

I haven't tested it very much, just Chrome, IE8, and IE8 in IE7 mode; though it shouldn't differ to much from Ben's.

It will also go through 5 or so extra loops in IE.

121 chars: with(document.createElement("b")){for(id=-1;innerHTML="<!--[if gt IE "+ ++id +"]>1<![endif]-->",innerHTML>0;);var ie=+id}

I haven't tested it very much, just Chrome, IE8, and IE8 in IE7 mode; though it shouldn't differ to much from Ben's.

It will also go through 5 or so extra loops in IE.

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Apr 8, 2011

David, I managed to get it even smaller, down to 112 chars:

with(document.createElement("b"))for(var ie=-1;innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",innerHTML>0;);

Owner

cowboy commented Apr 8, 2011

David, I managed to get it even smaller, down to 112 chars:

with(document.createElement("b"))for(var ie=-1;innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",innerHTML>0;);

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Apr 8, 2011

But if you can't stand the with, it's still pretty small at 113 chars:

for(var ie=-1,b=document.createElement("b");b.innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",b.innerHTML>0;);

And changing the var name from ie to i would shave off another 2 chars!

Owner

cowboy commented Apr 8, 2011

But if you can't stand the with, it's still pretty small at 113 chars:

for(var ie=-1,b=document.createElement("b");b.innerHTML="<!--[if gt IE "+ ++ie+"]>1<![endif]-->",b.innerHTML>0;);

And changing the var name from ie to i would shave off another 2 chars!

@davidmurdoch

This comment has been minimized.

Show comment
Hide comment
@davidmurdoch

davidmurdoch Apr 8, 2011

\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 clobber window.ie if it already existed.

\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 clobber window.ie if it already existed.

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Apr 8, 2011

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!

Owner

cowboy commented Apr 8, 2011

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!

@davidmurdoch

This comment has been minimized.

Show comment
Hide comment
@davidmurdoch

davidmurdoch Apr 8, 2011

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)

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)

@cowboy

This comment has been minimized.

Show comment
Hide comment
Owner

cowboy commented Apr 8, 2011

+1

@davidmurdoch

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

marcelkorpel Apr 8, 2011

Even better, you don't need explicit typecasting at all, just innerHTML will do the trick, too. ;-)

Even better, you don't need explicit typecasting at all, just innerHTML will do the trick, too. ;-)

@cowboy

This comment has been minimized.

Show comment
Hide comment
@cowboy

cowboy Apr 8, 2011

Marcel, have you actually even tried that cross-browser?

Owner

cowboy commented Apr 8, 2011

Marcel, have you actually even tried that cross-browser?

@marcelkorpel

This comment has been minimized.

Show comment
Hide comment
@marcelkorpel

marcelkorpel Apr 8, 2011

Yes, at least in FF4, IE8, IE8-acting-as-IE7, Chromium 10.

Yes, at least in FF4, IE8, IE8-acting-as-IE7, Chromium 10.

@kflorence

This comment has been minimized.

Show comment
Hide comment
@kflorence

kflorence Apr 8, 2011

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.

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.

@kflorence

This comment has been minimized.

Show comment
Hide comment
@kflorence

kflorence Apr 8, 2011

Also, firefox 3.6 needs the +innerHTML, can't use just "innerHTML"

Also, firefox 3.6 needs the +innerHTML, can't use just "innerHTML"

@kflorence

This comment has been minimized.

Show comment
Hide comment
@kflorence

This comment has been minimized.

Show comment
Hide comment
@kflorence

kflorence Apr 8, 2011

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

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

@Perelandric

This comment has been minimized.

Show comment
Hide comment
@Perelandric

Perelandric Oct 9, 2011

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".

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".

@Jaybuz

This comment has been minimized.

Show comment
Hide comment
@Jaybuz

Jaybuz Oct 10, 2011

(ie <= 7) is causing an error in IE8:

'Undefined' is null or not an object.

Jaybuz commented Oct 10, 2011

(ie <= 7) is causing an error in IE8:

'Undefined' is null or not an object.

@albell

This comment has been minimized.

Show comment
Hide comment
@albell

albell Apr 4, 2013

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 :)

albell commented Apr 4, 2013

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment