5

When researching JavaScript conditional comments for IE, I stumbled upon @cc_on. This seems to work. However, the wikipedia entry on conditional comments provides the following code for more robust IE detections, specifically IE6:

/*@cc_on
    @if (@_jscript_version > 5.7)
    document.write("You are using IE8+");

    @elif (@_jscript_version == 5.7 && window.XMLHttpRequest)
    document.write("You are using IE7");

    @elif (@_jscript_version == 5.6 || (@_jscript_version == 5.7 && !window.XMLHttpRequest))
    document.write("You are using IE6");

    @elif (@_jscript_version == 5.5)
    document.write("You are using IE5.5");

    @else
    document.write("You are using IE5 or older");

@end

@*/

The issue is, I'm getting an "expected constant" javascript error on !window.XMLHttpRequest.

Clearly Wikipedia needs some help, and I need to get this working. Can anyone help me out?

Sam Hanley
  • 4,707
  • 7
  • 35
  • 63
Jack
  • 512
  • 1
  • 4
  • 12
  • "More robust IE detections"? I think conditional comments provide the most robust form of IE detection possible. **Do not** rely on the JScript version to determine the IE version, as they are independent. See point 4 of http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html#c1774947112904387635 Moreover, you shouldn't use browser detection at all; use feature detection: http://www.nczonline.net/blog/2009/12/29/feature-detection-is-not-browser-detection/ – Marcel Korpel Mar 01 '10 at 03:43
  • 1
    @_jscript_version detection should be used only if you know the exact difference between the versions of jscript engine and you want to target that difference somehow - for example, emulate a missing feature. For example, jscript 5.1 didn't have Function's prototype call/apply methods defined, neither it had Array.prototype.push. So it is safe to detect this @_jscript_version and add programmatic support for these features. However, as Marcel said, it's not safe to assume that @_jscript_version of 5.1 maps to IE5.01 as you could easily get jscript updated from Windows Update. – Vitaly Sharovatov Mar 18 '10 at 08:20
  • 1
    @Vitaly: I don't want to nitpick too much, but the examples you gave can be tested with feature detection, so you don't also have to test for Javascript version >= 1.3 or something. Just use `if (!Function.prototype.call) { Function.prototype.call = foo; }`, etc., like Oz.js does: http://code.google.com/p/oz-js/source/browse/trunk/oz.js#224 – Marcel Korpel Mar 18 '10 at 19:08
  • I realise this is massively out of date but I stumbled across this when I was needing to do some old browser detection. Just for reference, in the call above you should be using the typeof operator to avoid the error you are getting. It's not how I would specifically test for IE6, but as I say just for reference your code should be.. `if (typeof window.XMLHttpRequest=="undefined") { /* code here */ }` – Ric Jun 18 '14 at 09:48

4 Answers4

4

Definitely no JS expert, but some searches found this for isolating IE6 from IE7 using jscript_version == 5.7:

/*@cc_on
if (@_jscript_version==5.6 ||
   (@_jscript_version==5.7 &&
      navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1)) {
  //ie6 code
}
@*/

Maybe it'll point you in the right direction.

Source: http://sharovatov.wordpress.com/2009/06/03/efficient-ie-version-targeting/

JBickford
  • 409
  • 2
  • 9
  • I'd like to clarify this a bit, but you're pretty much right. The issue turned out to be trying to call normal JavaScript within the precompiled conditional comment opperators "@elif" etc. When you just precompile the jscript version, and run everything else as traditional JavaScript, things compile and run just fine. – Jack Dec 04 '09 at 19:50
  • @Marcel Korpel - have you read my blogpost that JBickford is referring to? userAgent check is used *inside* conditional compilation block (so applied only to IEs) and there's no other way to determine a difference between IE7 which has jscript 5.7 and IE6 on Windows XP SP3 which also has jscript 5.7. – Vitaly Sharovatov Mar 16 '10 at 06:10
  • @Vitaly: I have to admit I didn't read your article and I was a bit harsh in my original comment, for which I apologize (and I deleted the comment). You have a point that you can safely detect the IE version in a conditional compilation block (and just that would be enough, also checking for JScript version is unnecessary), and browser detection *is* needed to check the `:hover` possibilities (they can't be detected, as far as I know), but I think using conditional comments is a more neat way to do this. That said, in most cases you could and should just use feature detection. – Marcel Korpel Mar 17 '10 at 22:43
  • @Marcel Just checking the navigator.userAgent string in a conditional compilation block is clearly not enough as IE6 can have both jscript of version 5.6 and 5.7 (when XPSP3 is installed). Therefore you have to combine both checks - for @_jscript_version AND navigator.userAgent if @_jscript_version returns 5.7. And there is no way to differentiate IE6 with jscript 5.6 or 5.7 from conditional comments - [if IE 6] will be parsed by both. Feature detection can do in most cases, but in some occasions with most obscure bugs you just need to know the exact version of jscript and trident. – Vitaly Sharovatov Mar 18 '10 at 08:06
  • @Vitaly: I agree with you that you need to look for the JScript version if you need specific features or want to tackle a bug involving JScript. The original question however was about detecting IE 6. – Marcel Korpel Mar 18 '10 at 11:40
3

I found a solution. The code is as follows.

<script type="text/javascript" charset="utf-8">
/*@cc_on
if (@_jscript_version > 5.7)
 document.write("You are using IE8");
else if (@_jscript_version == 5.7 && window.XMLHttpRequest)
 document.write("You are using IE7");
else if (@_jscript_version == 5.6 || (@_jscript_version == 5.7 && !window.XMLHttpRequest))
 document.write("You are using IE6");
else if (@_jscript_version == 5.5)
 document.write("You are using IE5.5");
else
 document.write("You are using IE5 or older");
@*/
</script>
Just a learner
  • 26,690
  • 50
  • 155
  • 234
  • 1
    Are you blind? That's the same chunk of code he included in his question. – Josh Stodola Jan 28 '10 at 16:42
  • 8
    Hi Josh, I changed @if...@elif...@else...@end to if...else if...else. I found some code in @if...@elif...@else...@end will not execute properly such as the **window.XMLHttpRequest** part. But it works well in normal if statements. – Just a learner Jan 29 '10 at 01:52
2

I've been using this nice one-liner for years:

var IE; //@cc_on IE = parseFloat((/MSIE[\s]*([\d\.]+)/).exec(navigator.appVersion)[1]);

Small and accurate (tested in IE 6-10).

Note to those who use grunt. be sure to set preserveComments: 'some' if you use the uglify plugin to make sure conditional comments are not removed.

will Farrell
  • 1,733
  • 1
  • 16
  • 21
  • Where did you found this nice one-liner? – yckart Jun 18 '13 at 23:35
  • @yckart I wrote it. You can see my latest version at https://github.com/willfarrell/angular-io/blob/master/src/scripts/ie.js that incluedes a chromeframe check (which will be unneccessary Jan 2014, due to chrome fame no longer being maintained). – will Farrell Jun 26 '13 at 21:09
0

maybe a bit late to the party but I also came across this problem, had a blast at it and my solution was as follows, hope it helps https://github.com/davesmiths/isIE

var isIE = false;
/*@cc_on isIE = @_jscript_version;@*/
if (isIE !== false) {
   if (isIE == 5.8)
       isIE = 8;
   else if (isIE == 5.7 && window.XMLHttpRequest)
       isIE = 7;
   else if (isIE == 5.7 || isIE == 5.6)
       isIE = 6;
   else if (isIE <= 5.5)
       isIE = 5;
} 
davesmiths
  • 201
  • 2
  • 3