47

In order to detect IE most Javascript libaries do all sort of tricks.

  • jQuery seem to add a temporary object into your pages's DOM to detect some features,
  • YUI2 does regex on the user agent in its YAHOO.env.ua = function() (file yahoo.js)

After reading this answer it came in my mind that it's true, in order to detect simply IE in Javascript we could simply add to our pages:

<!--[if IE]><script type="text/javascript">window['isIE'] = true;</script><![endif]-->

<script type="text/javascript" src="all-your-other-scripts-here.js"></script>

Now the window.isIE variable is set for all our Javascript code, by simply doing:

if(window.isIE)
   ...

Beside the fact that this might result in being a pain because it has to be added in all pages, are there any issues/considerations I might be unaware of?


FYI: I know it's better to use object detection rather than browser detection, but there are cases where you still have to use browser detection.

Community
  • 1
  • 1
Marco Demaio
  • 33,578
  • 33
  • 128
  • 159
  • One main reason that JS libraries would try to detect IE with JavaScript instead of conditional comments is that with conditional comments you need to add another script to your page (and this one even looks weird). This might confuse some people (new programmers) or annoy others. – jhartz Nov 12 '10 at 21:29
  • 1
    You forgot to close your SCRIPT element inside the conditional comment ... – Šime Vidas Nov 12 '10 at 21:30
  • In a perfect world you'd have just two sets of javascript engines to target, IE and all others. We don't live in that world. Hell never mind, in a perfect world you'd have just one engine and all of this would be bunk. (My point is that you often need more than just if !ie) – Jason Benson Nov 12 '10 at 21:36
  • @Marcel Korpel: thanks, smart snippet of code, but I disagee in code that adds DIV or any other stuff to the DOM. A final user using that snippet might not know how it works and might call in his own code stuff like $('div').doSomething() thus woudl be called also over teh DIV added by the snippet. In the same way if I have 3 DIVs in my page I would expect document.getElementsByTagName('div') to returns 3 items and NOT 4. – Marco Demaio Nov 15 '10 at 21:48
  • 1
    The created div isn't added to the DOM, only created using `document.createElement` and thrown away after the function returns (because it's only assigned to a local variable). I just tested `document.getElementsByTagName('div').length` after the function is executed (in both IE and Firefox) and it returns the correct number of divs in my document. – Marcel Korpel Nov 16 '10 at 12:38
  • @Marcel Korpel: it's great. Answer my question by posting your nice little thingy and I will accept your answer. Thanks for sharing and for the follow up. – Marco Demaio Nov 19 '10 at 15:48
  • Please don't edit your question to copy/paste answers. – rds Mar 04 '13 at 14:57
  • 1
    This doesn't work anymore. Conditional comments are not supported anymore from IE10 – axelvnk Sep 30 '14 at 13:01

15 Answers15

58

James Padolsey put a little snippet on GitHub that I'll quote here:

// ----------------------------------------------------------
// 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 5) then:
// ie === undefined
// If you're in IE (>=5) then you can determine which version:
// ie === 7; // IE7
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------

// UPDATE: Now using Live NodeList idea from @jdalton

var ie = (function(){

    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;

}());

Of course all credits should go to James, I'm only the messenger (but please shoot the messenger if my copy-paste action erred).

Also look at the forks that were created. Paul Irish explained the inner workings in a comment.

Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
  • 12
    Conditional statements are [not supported on IE10 any more](http://blogs.msdn.com/b/ie/archive/2011/07/06/html5-parsing-in-ie10.aspx). – rds Mar 04 '13 at 14:57
  • Only conditional comments in HTML are not supported anymore (e.g. ``), not conditional statements in IE10. – Qantas 94 Heavy Apr 05 '13 at 06:54
  • I love this function, so I created a version below which works in IE10 and is called the same way so that anyone else using it can just drop in the replacement. – Sean Colombo May 20 '13 at 20:38
39

If you want to do it that way, I think it's much better to use Conditional Compilation instead as you can do it inside the javascript without requiring to change the html:

var isIE = /*@cc_on!@*/false;
AlfonsoML
  • 12,634
  • 2
  • 46
  • 53
  • 7
    @AlfonsoML What kind of weird hack is that? :) – Šime Vidas Nov 12 '10 at 21:45
  • 1
    @Šime Vidas - that is a "conditional compilation" javascript statement. It's an IE-specific feature, effectively a JS version of the HTML conditional comment (which makes it a perfect answer to this question, so definitely +1). See http://www.javascriptkit.com/javatutors/conditionalcompile.shtml for more info. – Spudley Nov 12 '10 at 21:51
  • 1
    @AlfonsoML: Neat! I'd never heard of such a thing. Thanks. –  Nov 12 '10 at 22:04
  • 20
    Please bear in mind that minifyers don't like such thinks; YUI Compressor gets angry, Google Closure Compiler chokes on it. – Marcel Korpel Nov 12 '10 at 22:34
  • 2
    This works. However, unlike conditional comments, with conditional compilation it's impossible to distinguish between versions of IE, only different versions of JScript engine (which can be swapped and replaced independently of IE version). – Tim Down Nov 12 '10 at 22:49
  • 5
    @AlfonsoML For years I've been reading about conditional comments and the userAgent string, and NOW you tell me that you can detect IE with this one line? :p – Šime Vidas Nov 13 '10 at 01:01
  • @AlfonsoML: +1 very interesting stuff. – Marco Demaio Nov 15 '10 at 08:58
  • 1
    does this still work on IE10? Anyone on Windows 8 who can tell us? – wlf Feb 22 '13 at 09:59
  • 4
    I tried it on IE10 on windows 7 and 8 and it didn't work. – Ritesh Mar 07 '13 at 22:14
  • @wlf: This still works with IE10 in my testing. In fact you _can_ test for versions of IE using this code: http://en.wikipedia.org/wiki/Conditional_comment#Conditional_comments_in_JScript – Qantas 94 Heavy Apr 05 '13 at 06:51
  • @Qantas94Heavy: No, you can't. JScript engines can be replaced while keeping the same IE version. – Marcel Korpel Apr 05 '13 at 10:26
  • @MarcelKorpel: Technically, that is true (and sometimes the unlikely occurs, to many people's dismay). However, new bugs almost always occur when the JScript version is updated - it's extremely unlikely that that would be that case. Practically all IE major revisions have used a new version number of JScript, so it's unlikely that this wouldn't be continued into the future. – Qantas 94 Heavy Apr 05 '13 at 10:40
  • @peterson IE11 has removed most of the ways to detect that it's IE because its behavior has changed so much that you should treat it as a standard browser and not IE. You should review why you want to detect a specific browser instead of checking the feature that you need. – AlfonsoML Nov 18 '13 at 14:41
  • @TOBlender: You don't need to shout. What do you mean by magnification? – cookie monster Jul 04 '14 at 17:47
  • Avoid using this technique of you are using a Minifier. It will strip the comments out, and your detection will fail. – TOBlender Jul 16 '14 at 16:15
  • @AlfonsoML, I agree about the merits of feature/object detection over browser detection. I'm testing my page in Chrome 37, Firefox 32 and IE11, as well as on mobile browsers (the latest versions of all of them as of today.) I have JavaScript to vertically resize one of the components on my page to the maximum without inducing the generation of a page-level vertical scrollbar. In IE, I need to subtract an extra 5px because it renders differently. What "feature" would I detect for that? (Not intended as a snarky comment. I'm a C# dev but still pretty new to ASP.NET.) – JMD Sep 18 '14 at 17:28
  • You should ask a new question explaining your problem and people can give you ideas about how to detect that situation, either with detection of the problem (for example by measuring some test elements) or by some raw ua parsing if there's nothing better. – AlfonsoML Sep 18 '14 at 21:08
26

Marcel Korpel's answer no longer works (in IE 10 it returns undef, so IE 10 appears as not being IE). NOTE: Now updated to work with IE 11 also.

This is a variant of that code, but which comes from Microsoft's recommendations. If you were using the previous code, you can just drop in this replacement since it is built to be called the exact same way.

Unlike conditional comments/compilation, it should also work fine with minimizers.

// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
// ie === undefined
// If you're in IE (>=5) then you can determine which version:
// ie === 7; // IE7
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9, IE10 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------
var ie = (function(){
    var undef,rv = -1; // Return value assumes failure.
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    var trident = ua.indexOf('Trident/');

    if (msie > 0) {
        // IE 10 or older => return version number
        rv = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    } else if (trident > 0) {
        // IE 11 (or newer) => return version number
        var rvNum = ua.indexOf('rv:');
        rv = parseInt(ua.substring(rvNum + 3, ua.indexOf('.', rvNum)), 10);
    }

    return ((rv > -1) ? rv : undef);
}());

updated to work with IE11. Thanks 'acarlon' for pointing out that it wasn't working, and 'mario' for code that I based the fix on!

Sean Colombo
  • 1,459
  • 17
  • 24
  • 2
    But this works with User-Agent string sniffing; the UA string can be easily spoofed, but the conditional comments cannot. Anyway, who needs to detect IE 10? You can test everything with feature detection nowadays, which is far to be preferred above browser detection (which was only needed to detect things that couldn't be detected with feature detection). – Marcel Korpel May 21 '13 at 09:23
  • 1
    @MarcelKorpel: It's very misleading for "if(ie){}" to return false in IE 10, given that it _is_ IE. With regards to spoofing, that's true. I think in most cases (all cases except security-related issues), if a user wants to spoof a user-agent, then it's fine to respond to the UA that they choose to represent themselves as. In my specific use-case, I'm interacting with Trello's API whose 'popup' authentication does not currently work in any version of IE (including IE10), so if(ie), I elect to use a different method (with a less optimal UI, but at least it works in IE). – Sean Colombo May 21 '13 at 14:14
  • 1
    This helped me out because I specifically needed to detect IE 10. –  Sep 11 '13 at 17:09
  • 2
    @Marcel If you want to pretend to be somebody else, feel free. This is supposed to help the average IE idiot (who won't be doing spoofing). If you want to pretend, that won't hurt anyone except (possibly) yourself. – bjb568 Mar 01 '14 at 05:33
  • 2
    This no longer works on IE11 as navigator.appName is not M$. This answer works though: http://stackoverflow.com/a/21712356/746754 – acarlon Mar 06 '14 at 01:34
  • @acarlon thanks for the update! You're right my code wasn't working in IE11 anymore. That answer wasn't working in IE9 coincidentally though. I've merged them together and have it tested in IE9 and IE11. I'll update accordingly. – Sean Colombo Mar 06 '14 at 15:39
  • 1
    Thanks, @SeanColombo. It's ugly but it works. – JMD Sep 18 '14 at 17:30
11

IE 11 has changed a lot and now many past methods of browser detection do not work. The below code works for IE 11 and earlier.

function isIE()
{
    var isIE11 = navigator.userAgent.indexOf(".NET CLR") > -1;      
    var isIE11orLess = isIE11 || navigator.appVersion.indexOf("MSIE") != -1;
    return isIE11orLess;
}
webber55
  • 329
  • 4
  • 13
  • This seems really good, but why do you use ".NET CLR" instead of "Trident"? – Lightningsoul Feb 27 '14 at 09:13
  • Thanks, I'm using this to alert() then redirect IE users to http://browsehappy.com/ :) For a personal web app, an alternative steam library: http://sam.nipl.net/free-games.html I don't want to go through the pain of making it work in IE at the moment! – Sam Watkins May 05 '14 at 04:01
  • @Ligntningsoul: searching for ".NET CLR" emphasizes this is a Microsoft technology and it is not likely to change in the near future. – webber55 Jul 02 '14 at 14:37
  • 1
    This is by far my favorite answer. It works & it's concise. Thanks @webber55 – Trev14 Apr 06 '17 at 22:29
6

I think I have what you are looking for. You can get the Full Version of Internet Explorer as a string "AA.BB.CCCC.DDDD" using Javascript and clientCaps.

http://www.pinlady.net/PluginDetect/IE/

It appears to work for IE 5.5 and higher (including IE 10). It is immune to the navigator.userAgent/document mode/browser mode. There is no need for conditional comments, or any extra HTML elements. It is a pure Javascript solution.

I am not certain at this time how IE Mobile behaves, but you can always use a backup detection method in case this clientCaps method fails.

So far, I gotta say, it works pretty well.

Eric Gerds
  • 136
  • 1
  • 1
4

I think you answered your own question: first, it only detects IE, so the script would in essence be splitting the universe of browsers into 2 parts: IE and <everythingelse>.

Second, you'd have to add a wacky looking comment to every HTML page. Given that wide-ranging JavaScript libraries like jQuery and YUI have to be "easy" to insert/utilize for a breadth of sites, you would automatically be making them harder to use out of the gate.

jmbucknall
  • 2,061
  • 13
  • 14
3

navigator.userAgent exists if browser detection (rather than feature detection) is really needed, and jQuery uses it to get the information for the $.browser object. It's much nicer than having to include an IE-specific conditional comment in every page.

PleaseStand
  • 31,641
  • 6
  • 68
  • 95
  • 3
    Browers can fake their userAgent strings, but conditional comments execute only in IE without exception. – Šime Vidas Nov 12 '10 at 21:37
  • 1
    @Šime Vidas: True, although I wonder: how many users are faking their user-agent strings? – PleaseStand Nov 12 '10 at 21:39
  • @Sime Vidas: not users but Trident (teh IE engine) might be used on many browsers that are not exactly IE (mobile broesers maybe) and browsers do fake many times the userAgent string to pretend being IE or similar, that's why object detion is better than browser detection when possible. – Marco Demaio Nov 12 '10 at 21:44
  • @Marco Users, too. For example I fake the iPhone string to be able to view iPhone versions of web-pages on my desktop browser :) – Šime Vidas Nov 12 '10 at 21:48
  • @Sime Vidas: interesting, well one reason more to avoid using userAgent – Marco Demaio Nov 12 '10 at 22:04
  • 2
    @ŠimeVidas Isn't that a reason to use user-agent? If the user wants the page to look like IE, then let them set the User-Agent to something IE. If you want to test a mobile site, it should respond to an iPhone user agent. – Cobby Feb 08 '12 at 04:44
  • People who fake their user agent deserve to get broken web pages :) – Sam Watkins May 05 '14 at 04:03
2

Here you can find some really simple hacks for browser-detecting: http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/

var isIE = IE='\v'=='v';
yckart
  • 32,460
  • 9
  • 122
  • 129
2
var version = navigator.userAgent.match(/(msie) (\d+)/i);
console.log(version);

something quick I wrote quick after looking at this question in case anyone wants it.

** EDIT **

Per Johnny Darvall's comment below, I'm adding a link for anyone who is trying to sniff out Internet Explorer 11:

http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx

Jacksonkr
  • 31,583
  • 39
  • 180
  • 284
2

I'm using that code

var isIE = navigator.userAgent.indexOf(' MSIE ') > -1;

Viktor Fursov
  • 123
  • 1
  • 8
1

Checking for browsers is a bad idea - it's better to check for browser features instead. For example, usually you check if the user is using IE because you want to use some feature not supported in IE. However, can you know ALL current and future non-IE browsers will support that feature? No. So the way e.g. used by jQuery is better: It creates and executes small testcases checking for certain bugs/features - and you can simply check stuff like if(browser_supports_XYZ) instead of checking if the user is using a specific browser.

Anyway, there are always cases where checking for the browser is necessary because it's a visual bug you cannot test for using a script. In this case it's better to use javascript instead of conditional comments because you have the browser check right at the position where you need it instead of at some other place (imagine a .js file where you check for isIE which is never defined in that file)

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 1
    I did not give you -1, but I couldn't smile to whoever gave it to you. Read the bottom of my question. – Marco Demaio Nov 12 '10 at 21:46
  • 1
    what test do you suggest running for detecting if a browser supports alpha in .png and even better in .gifs. – Marius Bughiu Apr 09 '12 at 13:22
  • 1
    Sounds like "goto considered harmful". I need to check for IE, so I can redirect those people to get a better browser ;) – Sam Watkins May 05 '14 at 04:04
  • There are some things you can't feature detect, like how a browser handles multiple file downloads from a button trigger. For everything else, there's feature detection – Smegger Jan 21 '15 at 10:22
0

For my use case, I really just need to detect if lower than IE9, so I use

if (document.body.style.backgroundSize === undefined && navigator.userAgent.indexOf('MSIE') > -1)
{
//IE8- stuff
}
chiliNUT
  • 18,989
  • 14
  • 66
  • 106
-1

Why don't you just program in HTML5, and check that

if ( window.navigator.product !== "Gecko" )

?? True, this will include IE11 in the "Gecko" bunch, but isn't it supposed to be good enough now?

Note: the HTML5 spec. says that navigator.product must return "Gecko"... and IE10 and earlier all return something else.

Douglas Held
  • 1,452
  • 11
  • 25
  • https://developer.mozilla.org/en-US/docs/Web/API/NavigatorID.product Deprecated function, that was also never to be used for feature/browser detection. – Tristan Jan 07 '15 at 13:02
  • IE 11 still breaks when the other browsers seem to do just fine. I was doing some jQuery fades & content swaps today & IE 11 was the only one that decided not to work. – Trev14 Apr 06 '17 at 22:31
-1
  • It pollutes global namespace
  • It requires changes in two files.
  • It works in IE only
  • Technically, a conditional comment is still a comment
user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • Point 1) It does NOT POLLUTE GLOBAL namespace, I use it in window object. Point 3) watch out that IT WORKS ON ANY BROWSERS the if condition returns false on other browser, it does not break, I'm simply checking for an object property. – Marco Demaio Nov 12 '10 at 22:08
  • 2
    @Marco `window['isIE'] = true;` is basically the same as `var isIE = true;` (in global code), since `window` points to the global object. However, using one global property to detect IE is no big deal. – Šime Vidas Nov 12 '10 at 22:31
  • 1
    1) "window" is the global object. 3) Right. I meant to say that conditional comments work in IE only. – user123444555621 Nov 12 '10 at 22:32
  • Well, that's what the OP wants. He wants them to execute in IE, and be ignored in other browsers. – Šime Vidas Nov 12 '10 at 22:34
-1

This works quite well,
var isIe = !!window.ActiveXObject;

Ewen
  • 1
  • 7
    I don't know if it works in IE9. Quoting MSDN: "In versions of Internet Explorer earlier than Internet Explorer 9, some web authors used window.ActiveXObject to serve content specific to Internet Explorer. This practice is strongly discouraged." [ref. http://msdn.microsoft.com/en-us/library/ff974676(v=VS.85).aspx] – Marco Demaio Oct 01 '11 at 17:02