Friday, August 20th, 2010

Attack of the IE Conditional Comment…

Category: IE

<p>Just in time for Friday, James Padolsey wins the award for most creative Internet Explorer detection code:

javascript
< view plain text >
  1. // ----------------------------------------------------------
  2. // If you're not in IE (or IE version is less than 5) then:
  3. //     ie === undefined
  4. // If you're in IE (>5) then you can determine which version:
  5. //     ie === 7; // IE7
  6. // Thus, to detect IE:
  7. //     if (ie) {}
  8. // And to detect the version:
  9. //     ie === 6 // IE6
  10. //     ie > 7 // IE8, IE9 ...
  11. //     ie < 9 // Anything less than IE9
  12. // ----------------------------------------------------------
  13. var ie = (function(){
  14.     var undef, v = 3, div = document.createElement('div');
  15.    
  16.     while (
  17.         div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i>< ![endif]-->',
  18.         div.getElementsByTagName('i')[0]
  19.     );
  20.    
  21.     return v > 4 ? v : undef;
  22. }());


[CC-A by Noah Sussman]

That’s a pretty creative use of IE Conditional Comments.

[via jdalton]

Posted by Brad Neuberg at 6:00 am
25 Comments

++---
2.8 rating from 6 votes

25 Comments »

Comments feed TrackBack URI

does this avoid the problem with conditional comments in IE8 blocking downloads?

see http://www.phpied.com/conditional-comments-block-downloads/

Comment by useful — August 20, 2010

Scott Jehl already did this: http://gist.github.com/358029, I think he deserves the award.

Comment by RyanMorr — August 20, 2010

@RyanMorr, indeed, Scott deserves the award. I wasn’t aware that it had been done before.

While I am biased, I prefer mine. It’s terser and introduces a single variable that’ll either be a number or ‘Undefined’ (for non IE browsers). It doesn’t require you to call it as a function. Additionally it allows basic version querying with syntax that we’re all used to: `ie = 7` etc.

I do like Scott’s since it exits early in non IE browsers (using conditional compilation).

I think a mixture of the two solutions would be best.

Comment by jpadolsey — August 20, 2010

Ah, Ajaxian screwed up those expressions. Once again: `ie < 7`, `if(ie)…`, `if >= 7` etc.

Comment by jpadolsey — August 20, 2010

@ryan – I think James’ is cleaner and makes more sense in that its only executed once. Scott’s does cache but its not as if the version will change between calls.

Comment by kissmyawesome — August 20, 2010

Thanks for pointing out Scott’s version, I think I like his better for some reason. I can’t say why exactly though.

Comment by travisalmand — August 20, 2010

I like it, but why use the italic tag? Why not use an id or inject a specific class on the body – which you could then hook into for css styling.

Comment by cancelbubble — August 20, 2010

It’s funny, the other day Scott tried to convince me that I helped him write some “IE conditional comment” code, but I just couldn’t remember. Thanks for the proof! :D

Comment by benalman — August 20, 2010

@cancelbubble – the choice of tag is arbitrary, its only purpose is to see if the browser can detect a tag inside the conditional comment.

Comment by kissmyawesome — August 20, 2010

Over on the original gist of this code snippet, jdalton and I explained a bit more about how it works, in case anyone wants some of the wtf demystified:
http://gist.github.com/527683#gistcomment-7599 (and jdalton’s ECMAscript language decomposition is a few more down)

Comment by PaulIrish — August 20, 2010

http://dean.edwards.name/weblog/2007/03/sniff/

Comment by deanedwards — August 20, 2010

I dig that Jame’s original gist didn’t rely on on conditional compilation, @cc_on, and instead used only conditional comments. I never like using conditional compilation in case some JS minifier removes them. It’s just one more thing to worry about.

Comment by jdalton — August 20, 2010

http://jsperf.com/ie

–dean wins

Comment by shawndumas — August 20, 2010

Nice technique, although don’t IE conditional comments have some uncommon cases where they don’t work? Then again, finding a more reliable sniff for IE6/IE7 detection is hard too!

IMHO it is OK to a target particular browser version to work around bugs, where that browser version is “obsolete” (version only getting security patches or no longer maintained). Otherwise “feature detection” seems to be a better technique to me.

@jdalton: If you are worried, put the conditional comment inside a string – no minifier should ever modify a string e.g.:

var ieJsVer = Function(‘return/*@cc_on @_jscript_version @*/’)();

Comment by morrisj — August 21, 2010

It’s old story, I’ve used that while ago. However instead of ‘undefined’ I used ‘null’ for a purpose.
I dependent modules I’ve added detection whether ie method was fired – if ‘ie’ was undefined it was sign that no detection have been made – quite important overlook ;-)

Comment by medikoo — August 21, 2010

.. anyway, now we’re in the age where we should stay away from such sniffers but detect functionalities instead. I would call that sniffer deprecated ;-)

Comment by medikoo — August 21, 2010

http://jsperf.com/ie

dean ftw

Comment by shawndumas — August 21, 2010

Been using this technique for over a year now but didn’t think is was of much interest to anyone, guess I was wrong! Also suggested it as a fix to a MooTools issue last December:

https://mootools.lighthouseapp.com/projects/2706/tickets/798-ie78-incorrectly-identified-as-trident4

Comment by raider5 — August 21, 2010

it’s like groundhog day… I guess that feeling I had when posting that last comment wasn’t deja-vue after all. sorry…

Comment by shawndumas — August 21, 2010

@medikoo It’s not like the capabilities of IE 8 and below are going to change.

Comment by Darkimmortal — August 22, 2010

@Darkimmortal
You’re missing the point. Any quirk that you think belongs to a specific version of IE may belong to some other browser too, so by using feature detection you fix not only IE but *any* other browser having the same quirk. And you don’t need to identify or test for them independently – not hard to see why feature detection is preferred.

Comment by RobG — August 22, 2010

So if we combine this with Paul Irish’s CSS conditional comments technique we get :

document.documentElement.className += ( /*@cc_on!@*/ true) ? “ie”+(parseInt(navigator.userAgent.match(/msie\s(\d+)/i)[1])) : “

Comment by simon000666 — August 23, 2010

document.documentElement.className += ( /*@cc_on!@*/ true) ? “ie”+(parseInt(navigator.userAgent.match(/msie\s(\d+)/i)[1])) : “”;

missed the end.

Comment by simon000666 — August 23, 2010

Dean Edwards’s code is not equivalent to this. Unlike conditional comments, conditional compilation cannot detect IE versions: it can give you the version of JScript and which OS the browser is running on, but that’s about it. If you absolutely have to detect the version of IE, conditional comments are the way to go, though you should be using feature detection instead for pretty much everything.
One final point is that turning conditional compilation on (which is what Dean’s code does) can have unexpected side effects: a comment such as //@TODO Fix this code will throw an error in IE if and only if conditional compilation is turned on.

Comment by timdown — August 23, 2010

Moreover, IE6 SP3 and IE7 have the same JScript version. You have nothing to do with conditional compilation.

Comment by GreLI — August 23, 2010

Leave a comment

You must be logged in to post a comment.