28

Just stumbled upon an issue. When trying to detect IE 11 (the beta version currently on air) using Jquery, the result is 'firefox'. The same code detect IE 10. I need to know what browser the user is using in order to display different instructions.

I am testing in Oracle VirtualBox if it matters. The OS is Win 7.

Here's the code:

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
var browser = function() { 
if ($.browser.msie) return "ie";
var ua = navigator.userAgent.toLowerCase();
if ($.browser.mozilla/* && /firefox/.test(ua)*/) return "firefox"; 
if (/chrome/.test(ua)) return "chrome";
return /*"#"*/'unknown';
} ();

alert (browser); // This return firefox
alert ($.browser.version); // This returns 11.0 - the CORRECT version of IE
</script>

As you can see, Jquery can find the browser version, but not the browser name. Any idea how to bypass it?

mason
  • 31,774
  • 10
  • 77
  • 121
Ehud Grand
  • 3,501
  • 4
  • 33
  • 52
  • 1
    Since it's not out yet, I guess jQuery doesn't support it. Just do the sniffing yourself. It's not difficult. – Dave Sep 08 '13 at 13:20
  • I think developing for IE 11 is a little tricky at the minute given that it's still in beta - at the minute I just test for "rv:11.0" in the user agent string to see if it's the latest version of IE. – Robbie JW Sep 08 '13 at 13:21
  • 1
    *"I need to know what browser the user is using in order to display different instructions."* One of the few valid browser-sniffing use cases. :-) That said, I would **always** be sure to offer a link to other browser instructions as well, just in case. – T.J. Crowder Sep 08 '13 at 13:21
  • 1
    you can see this Question http://stackoverflow.com/questions/17447373/how-can-i-target-only-internet-explorer-11-with-javascript –  Sep 08 '13 at 13:22
  • @T.J.Crowder: what about handling box-model differences? – Eldarni Sep 08 '13 at 13:29
  • 1
    @RickyBaby IE uses the same box model as other browsers since IE6. – duri Sep 08 '13 at 13:34
  • I don't think that the `browser` part will get any updates in future because it is not part of jQuery anymore (only part of the migration script). – t.niese Sep 08 '13 at 13:36
  • @RickyBaby: Those are easy to feature-detect. – T.J. Crowder Sep 08 '13 at 13:36
  • You could look into using a different UA parsing lib such as [ua-parser](https://github.com/tobie/ua-parser). – Whymarrh Sep 08 '13 at 23:30
  • 5
    You should never need to do that. – SLaks Aug 13 '14 at 18:22
  • 1
    for what its worth, i'm currently using chrome, and $.browser.chrome = undef and $.browser.safari = true. [Jquery's .browser is depreciated](http://api.jquery.com/jquery.browser/) – Kevin L Aug 13 '14 at 18:22
  • Info: Chrome was built over Safari. – emerson.marini Aug 13 '14 at 18:23
  • 3
    because Microsoft doesn't want you to be able to detect IE11 so that you can't target their browser specifically to suggest people change browsers or disable functionality based on browser used. – Kevin B Aug 13 '14 at 18:23
  • 1
    If that `$` is a jQuery object, you should tag this with [tag:jquery]. You should also know that using `$.browser` is so strongly discouraged that they removed it in jQuery 1.9. – user229044 Aug 13 '14 at 18:24
  • `$.browser` has been deprecated on v1.3 and removed on v1.9. So you have an idea if you could rely on this. – emerson.marini Aug 13 '14 at 18:24
  • From the jQuery documentation: _This property was removed in jQuery 1.9 and is available only through the jQuery.migrate plugin. Please try to use feature detection instead._ – emerson.marini Aug 13 '14 at 18:25
  • 4
    If you were an IE 11 browser, would you really want people to know it? – Erlesand Aug 13 '14 at 18:25
  • here's the best solution I've found: http://stackoverflow.com/a/20201867/2047385 if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) { // is IE11 } – xorcus May 20 '15 at 12:57

5 Answers5

64

The final solution:

if (!!navigator.userAgent.match(/Trident\/7\./))
  return "ie";  

We can only hope that the release version will act the same.

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
Ehud Grand
  • 3,501
  • 4
  • 33
  • 52
  • 9
    This is what I recived from Microsoft: "The "bug" you're reporting is part of the HTML5 specification and is intentional. This is part of an industry wide effort to discourage websites which customize content to different browsers." – Ehud Grand Sep 09 '13 at 06:32
  • 5
    It would be easy for "the industry" to eliminate browser testing by simply conforming to spec. However even specs are notoriously flawed and implementations fare no better. Capability testing is clearly a better way to normalize development, but not all bugs/features can be detected. – evoskuil Nov 13 '13 at 09:35
  • 12
    `if (/Trident\/7\./).test(navigator.userAgent))` is better as `.test()` actually returns a boolean - as well as being much faster. Using `.match()` returns an array with the result. – Stephen Jenkins Nov 22 '13 at 19:19
  • 1
    Release version acts the same. Wonder why Microsoft says it's compliance to the spec while things actually break because other behaviors are NOT conforming to the spec. Right now I am trying to fix jWYSIWYG, that does not work in IE11 but does in IE8,9,10 and in all other major browsers that comply with HTML5 since much longer than IE. – Alex Mazzariol Mar 22 '14 at 18:13
  • I don't think it matters much why Microsoft decided to change, since jQuery stopped supporting browser detection ~ v 1.9. The migrate project is a workaround for as long as it's supported, but isn't the goal to get browsers to a point where you don't have to test the browser? I know we aren't close... – ps2goat Sep 26 '14 at 05:05
  • here's the best solution I've found: http://stackoverflow.com/a/20201867/2047385 if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) { // is IE11 } – xorcus May 20 '15 at 12:57
7

It's for compatibility reasons. Client code often performs browser detection instead of feature detection (which is a poor practice). So in an effort to make sure that clients properly use all of IE 11's capabilities Microsoft has made it so that IE 11 will report that it's Mozilla compatible.

So instead of doing browser detection, do feature detection. See Browser detection versus feature detection. There's some great libraries for that, with Modernizr probably being the most well known (and Microsoft ships it as part of the ASP.NET templates in Visual Studio).

See MSDN blog about IE 11 User Agent Strings.

Community
  • 1
  • 1
mason
  • 31,774
  • 10
  • 77
  • 121
5

The purpose of jQuery Migrate is to allow old badly-written code to run, not to encourage writing new badly-written code. Since that old badly-written code was created long before IE11 was released, it doesn't know about IE11 anyway and will probably misbehave regardless. The jQuery Migrate plugin won't be changed to detect IE11. If you are writing new code, don't use browser detection. Instead, use feature detection.

Dave Methvin
  • 1,458
  • 10
  • 12
  • 8
    I know this is gospel, but I don't think my code that uses browser plugins (and has to give very browser-specific user prompts) is "badly-written". Oh, wait, I know: "Don't use plugins!" Except my plugin is for document scanning... "Don't support scanning!" Except our customers need to scan millions of paper documents per year... "Make your customers stop using paper!" It's the Fortune 500 and the government... "Live in a different universe!" Oh, OK. Got it. – Spike0xff Nov 06 '13 at 15:18
  • 1
    If you need to detect Browser Brands for specific reasons ("Welcome IE11 User!") then write a plugin to do it. As a utility function it's not a good idea at all, which is why `$.browser` is gone. – Dave Methvin Nov 08 '13 at 17:00
  • @Spike0xff no-one would say don't support scanning that. What they'd say is: find another way to get the scans in than a cheap and cheerful solution now that costs way more in maintenance and security down the line. – Rob Grant Jan 23 '14 at 13:57
  • 1
    Yes @RobertGrant, I've heard and seen that advice more times than I'd like to count. Unfortunately it's really more of a guideline, because "find another way" is not guaranteed to produce any output, or even to terminate. But if you have a *specific* suggestion that applies to my *specific* problem, please, say on. – Spike0xff Jan 24 '14 at 19:25
  • If you think you've given enough detail for a specific suggestion then I look forward to seeing some companies drop out of Fortune 500 :) – Rob Grant Jan 27 '14 at 10:11
  • You said "find another way to get the scans in than a cheap and cheerful solution now that costs way more in maintenance and security down the line." It sounded like you knew everything you needed to know. I think back then would have been the time to ask for specifics. But please, go ahead and short FFF. Make your fortune. – Spike0xff Feb 09 '14 at 22:52
  • "Back then" I wasn't starting a conversation about your specific situation, I was just suggesting what real people would've said, as opposed to your straw man's crazy suggestions. No conversation about your situation required. The reason I mentioned specifics was because you demanded them (assuming that's what "say on" was meant to mean) without having provided any of your own. – Rob Grant Feb 24 '14 at 13:20
2

jQuery.browser is long deprecated and has been removed, you should use $.support or a better tool like Modernizr

David Fregoli
  • 3,377
  • 1
  • 19
  • 40
0

If you just need to know whether its IE following is the code

function isIE() {
var ua = window.navigator.userAgent; //Check the userAgent property of the window.navigator object
var msie = ua.indexOf('MSIE '); // IE 10 or older
var trident = ua.indexOf('Trident/'); //IE 11
if(msie > 0)
{
    console.log("IE less than 11 ");
}
else if(trident > 00)
{
    console.log("IE more than 11 ");
}
return (msie > 0 || trident > 0);
}
console.log(isIE());//returns true for any IE version.

While if you need to check version together you need to check the document.documentMode

function isIE11() 
{
    var ua = window.navigator.userAgent; //Check the userAgent property of the window.navigator object
    var msie = ua.indexOf('MSIE '); // IE 10 or older
    var trident = ua.indexOf('Trident/'); //IE 11
    if(msie > 0)
    {
        console.log("IE less than 11 ");
    }
    else if(trident > 00)
    {
        console.log("IS 11 ");
    }
    if(msie > 0 || trident > 0 && document.documentMode)
    {
        console.log("document.documentMode ::",document.documentMode)//document.documentMode must be 11 or Edge
        if(document.documentMode == 11)
        {
        return true;
        }
    }
    return false;
}
console.log(isIE11());

To see/change the version in IE you can go to emulation in the developer console.

Parameshwar
  • 856
  • 8
  • 16