if(!+"\v1") // true only in IEif("\v"=="v")// true only in IEtry{IE=window=!1}catch(e){IE=!0}
it works, doesn't it?
The reason is simple, if we consider "\v" as a vertical space, browsers interpreter that check in this way:
!(+
1
)
where "not one" is always false, considering that 0 is always casted as false, and every other number is casted as true.
Internet Explorer will ignore the vertical space, trying to cast a "v" character into a number, thanks to the sign (plus or minus, it does not matter)
// How IE interpreters the code
!(+"v")
// where
isNaN(+"v") === true
// and where NaN is implicitly casted as false
About conditional comments
I read a lot of comments in both Ajaxian and other places ... well, guys, this is a trick as conditional comment is.
The day IE will interpret correctly the "\v" character, Opera or some other browser could implement conditional comments as well.
That's my simple point of view:
conditional comments could be stripped out from minifiers (not MyMin) and make code difficult do understand or maintain while this 7 bytes trick is portable, minifier/packer safe, and extremely easy to maintain (the day IE will be able to return a false, we'll have solved almost every cross browser problem thanks to JS2 but just in case, all we need to do, will be a simple replace with the isIE.Next trick)
Note this trick is library/hack proof. If you think that execScript check is enough, for example, consider this: top["execScript"]=null and/or libraries that implements execScript for other browsers.
Useful and also tiny. What else can we ask!? ;-)
ReplyDeleteNice! Much better than...
ReplyDeletevar isIE=function() {
/*@cc_on
@if (@_jscript)
return true;
@else */
return false;/*
@end
@*/
}
yep, it does not use conditional comments. That's the plus ;-)
ReplyDeleteHehe it was a challenge to beat but...
ReplyDeleteIE=top.execScript?true:false
28!!! :)
Doh!
ReplyDeleteIE=top.execScript?1:0
21 :)
sure Gareth, that's why I edited my entry: my trick is hack proof ;-)
ReplyDeleteIE=!!top.execScript
ReplyDeleteand now read the note, your one is not a good check
I like the !! trick :)
ReplyDeleteYeah it can be overwritten but so can IE but I take your point.
Try / catch gives a small performance hit. So only use it if you MUST.. and there are no other options...
ReplyDeleteGareth, the point is that your trick is never reliable, while window or window property cannot be assigned in IE or it generates an Illegal assignment exception.
ReplyDeleteSo, if wherever you want to be sure that the browser is IE, if you load external scripts, for example, you can always perform something like this:
if(function(IE){
try{IE=this.window=!1}catch(e){IE=!0};return IE
}())
@V1, you are generally right, but there are a lot of tests in try catch that you can perform once in a session and will not slow down the application at all.
Did you miss my other comment?
ReplyDelete//Works fine
IE='\v'=='v'
Did you miss mine? :D
ReplyDeletevar IE = function(IE){try{IE=this.window=!1}catch(e){IE=!0}return IE}();
You can perform the check N times, if necessary, or use your own namespaced library object.
myCoolLib.IE = function(IE){try{IE=this.window=!1}catch(e){IE=!0}return IE}();
Andrea, I don't get your point because you can easily create a function with:-
ReplyDeletefunction isIE() {
return '\v'=='v';
}
and it event works on IE8
Gareth, I thought it was an assignment ... are you sure it is true only with IE? If it is, sounds amazing (pelase try IE8 as well, thanks)
ReplyDeleteAndrea yep positive. false in safari,ff,chrome,opera but true in IE7, IE8
ReplyDeleteDo I win now? ;)
YES :D
ReplyDeleteAnd how about:
ReplyDeleteie=/*@cc_on!@*/false;
or, if u need to know concrete version:
ie=/*@cc_on 'ie6'; @if(@_jscript_version==5.7) 'ie7'; @end @if(@_jscript_version==5.8) 'ie8'; @end@*/
NO conditional comments please ;-)
ReplyDeleteIE//@cc_on=1
ReplyDeleteis twelve bytes. Since we're specifically trying to detect IE (rather than detect a feature), conditional comments are the way to go. If IE9 suddenly supports \v then the test will break; conditional comments will not.
@Stuart Langridge
ReplyDeleteAwesome bit of code but that will raise a error in other browsers because IE will be undefined.
Dean Edwards long time ago, suggested me this code to get the IE version number:
ReplyDeletevar IEVersion = 0/*@cc_on+ScriptEngineMajorVersion()@*/;
I think is still working ;)
the Stuart check is not the best one indeed.
ReplyDeleteIE=/*@cc_on!@*/!1;
this one is better ;-)
anyway, no conditional comments please 8-)
Thanks for greate and cool tip :).
ReplyDeleteI've found a way to detect every major browser using js quirks :D
ReplyDeletehttp://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/
Absolute genius!
ReplyDeletehas anyone submitted this IE check?
ReplyDeleteIE=(document.selection);
Does \v have some special meaning in IE?
ReplyDeleteOr is the trick specifically that \v *doesn't* mean anything, so IE reads it as "a backslash followed by a v", but the other browsers just ignore the backslash and interpret it as a v?
"\v" in IE means "v", so IE reads it as "v" without the backslash (other way then)
ReplyDeleteother browsers obviously do not consider those two character the same ;-)
oxotnick from the slackers forums even managed to reduce it:-
ReplyDelete!-'\v1'
Holy Jesus, what a crap! =;->
ReplyDelete1. You don't know, whether future versions of IE behave the same way.
2. Don't blame yourself with conditional comments. Conditional comments are HTML stuff. The (even longer existing) version for JScript is called conditional compilation
3. Use conditional compilation for determing an IE. Yes, maybe CC will be used by another browser some day, but then, this other browser would use JavaScript, not JScript. So use CC and test for JScript as Gareth shows with @_jscript. Another browser vendor would implement another, new variable, i.e. @_javascript or @_ecmascript (although: the constant __ECMASCRIPT_VERSION__ is already on the way ...), at least for compatibility reasons. And if a browser vendor would really license MS' JScript (suck!) itself (so @_jscript would really trigger at Non-IEs), what makes you think, that the vertical-tab-hack wouldn't trigger on that script engine too? In that case, it could be much more complicated, to identify an IE ...
4. Last, but not least, it is not, not, NOT possible to conclude on the IE version from the version of the scripting engine! Both are totally separated - in theory and practice! I.e. IE 6 has come natively with JScript 5.6, so i.e. @_jscript_version will report "5.6" (see DPP's comment). Don't update the IE, but just install (or update) the Windows Scripting Host - a scripting engine for the Windows desktop, and you automatically update the IE's scripting engine too (my IE 6 reports JScript version 5.7, but is nonetheless an IE 6 with all its bugs and behaviours, and not an IE 7).
If you really want to know the IE-Version: use CSS hacks, which can be done dynamically too, and read out the resulting code by the styleSheets-object and its rules-collection (for easy, browser-independent setting and getting CSS rules see cssRule() ). If the IE doesn't recognize the CSS, then he will tell you (rule "UNKNOW"). But IE 8 has a new feature for determining the browser version respectivly the mode, the browser runs in (i.e. IE 8 emulating an IE 7) introducing document.documentMode (a "successor" of the already known document.compatMode). So in future there should be no need for using CSS hacks anymore ...
Cybaer do I miss something? You posted as nobody else had a clue about conditional comments. If you read comments I already wrote this:
ReplyDeleteIE=/*@cc_on!@*/!1;
which is the shortest conditional comment to know if the browser is IE.
The point is, still, this trick is about a "feature" presents only in IE so NO CONDITIONAL COMMENTS. Got the point? :)
Hi Andrea,
ReplyDeleteyes, sorry, you miss something. IMHO you miss two things:
First, your example is not a conditional comment, which is like this: <!--[if IE]>I'm IE<![endif]--> (a special sort of HTML comment, which you know for sure ;-)).
But what you mean is conditional compilation (a special sort of JScript comment).
No need to mix up the names though. ;-) They are defined as is - and docs can be found in the net by that names.
And second, with this shortest type of conditional compilation you wrote, you can get up in the mess, if (and only if) another browser vendor also implements conditional compilation. To avoid that (somewhere less probable but possible) situation, it would be safer to check for @_jscript. (Indeed, I would like both CC's to be implemented on other browsers! ;-))
So you are right - at the moment! Only IE knows conditional compilation (and @_jscript is always true) for now. The short line fullfill its task.
But if a browser like Mozilla would start to implement conditional compilation too, this short line will set your variable IE to true, although the browser is a Mozilla and not an IE. Because of that it is just safer, to check for @_jscript, because a Mozilla conditional compilation would, no: has to set this variable to false.
Both features, conditional compilation and conditional comments are proprietary IE stuff for now. But both features are able to be implemented in other browsers (think also of not yet working, but theoretically possible <!--[if Moz]>I'm a Mozilla<![endif]-->).
Got the point? ;)
still, conditional compilation is a feature as !+"\v1" is. If we need to think about future problems with @cc_on, why on earth we cannot simply do the same with !+"\v1"?
ReplyDeleteWhat I mean is that:
1 - the trick is without conditional comments (compilation) on purpose
2 - whatever we are talking about is a "feature" of a single browser.
Are you sure M$ will support @cc_on or @_jscript in the future?
'Cause rumors say IE9 could adopt WebKit, in that case this "trick" will work perfectly, your one will mess up your code (but again, we are talking about 1 single variable definition, I'll never get this "religious war" about a 7 bytes to change when and if necessary in a far future ...)
Got the point? :P
> Are you sure M$ will support @cc_on or @_jscript in the future?
ReplyDeleteNo, I'm not sure.
Sure, M$ is particularly concerned to be backwards compatible to older IEs. They say that, and you can see that in maaaany examples. But nobody can be sure. At least, because CC is (in my opinion as "ordinary JS developer") often used just for IE workarounds.
And if, in a distant future, an IE x would be complete compatible to other browsers, maybe there is no need for CCs anymore (although I think, MS didn't invented CCs only for that purpose =;-), so a sort of "IE JScrip developer" could see CCs with other eyes than I do).
On the other hand: what makes you think, that no other browser in the future would never handle a vertical tab the way IE does now? What makes you even think, that there isn't such a browser today on the market? There are maaany HTML clients out there beside the big ones we know for the standard computer. I don't know all of them. I suppose you also don't know them all, don't you?! ;-)
Another small example: JS can not handle text variables with linebreaks in it like PHP does:
$phptext="line1
line2
line3";
But newer JS-browers can handle a sort of that:
jstext="line1\
line2\
line3";
Older JS-browsers can't handle that, and need the oldschool type:
jstext="line1\nline2\nline3";
What I want to say is, I think it's just better to rely on a documented feature from a company which is well known to preserve backwards compatibility at many costs (if not at all costs - because they made their software incompatible to the rest of the world, for business purposes and don't want their customers tell "what we did was wrong, sorry for your inconvenience, but don't stop to pay us in the future either" ;->).
I don't want to rely on something I could barely overview ...
So I think the opinions are exchanged, let the folks decide on their own. ;-)
PS: Change of subject to the mentioned "IE version recognition" because I really don't want that to be forgotten are overviewed: Don't try to get the IE version out of the JScript version. This is not a point of "future" or "opinion", this is just provable fact in todays computing ... ;-)
Cybaer, as long as this trick works perfectly I do not get a reason to change the subject.
ReplyDeleteWe all do not know about the future and your assumptions could not be correct.
Think about IE5 for Mac, they simply stopped to support it.
If IE9 will adopt WebKit they could choose to leave old IE to the history.
So we still are in the future and opinion subject.
Finally, as I said before: I'll never get this "religious war" about a 7 bytes to change when and if necessary in a far future.
the isIE or IE variable is a single point in an entire application, if somebody is scared about maintain their applications, something we all have to do in any case, well, they can decide which way is better.
Hi Andrea,
ReplyDeletesorry, misunderstanding!
With "change of subject" I didn't thought of this blog entry's title, but about the subject of our "comment dispute". Because DPP and kentaromiura wrote in their comments, that it is possible to get the IE version by checking the version of the scripting engine. "Our" dispute is one based on "opinions". But the tips for version checking are just wrong, which should not be overlooked ...
Best regards!
Nice one!
ReplyDeleteI used your !+"\v1" detection in my simple flash embedding script and it works like a charm.
Thank you!
I think my decision better
ReplyDeleteie=!-[1,]
so @Aleko, please enlighten the world about how your 9 bytes are better than Gareth 8 ...
ReplyDeleteWhy 9 ??? 6!!!!
ReplyDelete!-[1,]
or even
-[1,]
(but it returns false in ie and true in all others)
my apologies, I counted in a wrong way. Just one question: are you sure this is not going to throw errors in older IEs? If not, we've got a new winner ;-)
ReplyDeleteI think next test to do is about minifier/compilers ... as example, Closure Compiler will throw an error. It won't with Gareth one since that's just a string.
ReplyDeleteI tested it in IETester and errors have not received - conversion is simple. About closure compiler - i'll think...
ReplyDeletesorry for my rude english, i'm russian =)
Compressors has swallowed it without errors (http://compressorrater.thruhere.net/)
I always use:
ReplyDeletevar ie=0/*@cc_on +(document.documentMode||@_jscript_version*10-50)@*/
Why?
Each IE version has other bugs so i know the version of IE AND if it is IE.
This comment has been removed by the author.
ReplyDeleteAmazing trick..very helpful..keep posting like this.
ReplyDeleteif(!+"\v1") doesn't work after compress code with AjaxMin. Use top.execScript safer.
ReplyDelete> Are you sure M$ will support @cc_on or @_jscript in the future?
ReplyDeletetr
Thanks,
ReplyDeleteHelped me a lot. Hate IE
Useful post! I'm one of those who really deslike IE.
ReplyDeleteIE it not as bad as you said here...
ReplyDelete