59

I use the following snip of a script:

if ($.browser.msie && $.browser.version < 9) {
   extra = "?" + Math.floor(Math.random() * 3000);
}

It works fine with jQuery 1.8.3.

Now I updated jQuery to the new version 1.9.1 to use a new script.
Now I get the following error:

TypeError: Cannot read property 'msie' of undefined

I read the change log of the new jQuery version, but nothing should have changed
with msie

Any known bugs, tips or proposals?

Michael Schmidt
  • 9,090
  • 13
  • 56
  • 80
  • 6
    $.browser was removed in 1.9: http://jquery.com/upgrade-guide/1.9/#jquery-browser-removed – Andreas Schwarz Feb 15 '13 at 09:57
  • If you get an error like 'Cannot read property 'msie' of undefined', look at what it is saying is undefined, which will be the parent of the unreadable property – DrCord Jan 05 '15 at 16:27
  • There's a non-jQuery solution that pays regard to the fact that recent versions of IE had userAgent values that didn't clearly say it's IE: http://stackoverflow.com/a/21712356/2067690 – HumanInDisguise May 26 '15 at 08:33

11 Answers11

59

Since $.browser is deprecated, here is an alternative solution:

/**
 * Returns the version of Internet Explorer or a -1
 * (indicating the use of another browser).
 */
function getInternetExplorerVersion()
{
    var rv = -1; // Return value assumes failure.

    if (navigator.appName == 'Microsoft Internet Explorer')
    {
        var ua = navigator.userAgent;
        var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
            rv = parseFloat( RegExp.$1 );
    }

    return rv;
}

function checkVersion()
{
    var msg = "You're not using Internet Explorer.";
    var ver = getInternetExplorerVersion();

    if ( ver > -1 )
    {
        if ( ver >= 8.0 ) 
            msg = "You're using a recent copy of Internet Explorer."
        else
            msg = "You should upgrade your copy of Internet Explorer.";
    }

    alert( msg );
}

Source

However, the reason that its deprecated is because jQuery wants you to use feature detection instead.

An example:

$("p").html("This frame uses the W3C box model: <span>" +
        jQuery.support.boxModel + "</span>");

And last but not least, the most reliable way to check IE versions:

// ----------------------------------------------------------
// 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;

}());
Laurent.B
  • 213
  • 2
  • 14
Johan
  • 35,120
  • 54
  • 178
  • 293
38

$.browser was deprecated in version 1.3 and removed in 1.9

You can verify this by viewing the documentation.

Michael Schmidt
  • 9,090
  • 13
  • 56
  • 80
kicaj
  • 2,881
  • 5
  • 42
  • 68
  • 6
    I'm using a plugin with $.browser.msie, would this be acceptable just prevent the error?: $.browser={ msie: ( navigator.appName == 'Microsoft Internet Explorer') ? true : false } // this of course doesn't account for other possibilities, but seemed to fix the error. – David Hobs Aug 19 '13 at 10:55
  • Nice workaround (In my case I had no other option, but using a workaround) - works great for me – Rotem May 17 '14 at 16:02
  • It's a nice workaround, but will fail you on IE11 in IE11 navigator.appName is 'Netscape', not 'Microsoft Internet Explorer' – Hussam Apr 23 '15 at 09:20
  • 2
    Yes, obviously it's gone. Telling people to RTFM isn't a helpful answer. – Cerin Nov 11 '16 at 04:29
  • It wasn't obvious to the asker of the question and so it is helpful. – Antony D'Andrea Nov 28 '16 at 14:28
  • Hi @kicaj - I downvoted because this answer was not useful, since this was not a bug, and you did not provide tips or proposals as requested. I will happily remove if you update. – HungryBeagle Sep 15 '20 at 13:01
15

For simple IE detection I tend to use:

(/msie|trident/i).test(navigator.userAgent)

Visit the Microsoft Developer Network to learn about the IE useragent: http://msdn.microsoft.com/library/ms537503.aspx

user3144038
  • 401
  • 5
  • 4
13

The jQuery.browser options was deprecated earlier and removed in 1.9 release along with a lot of other deprecated items like .live.

For projects and external libraries which want to upgrade to 1.9 but still want to support these features jQuery have release a migration plugin for the time being.

If you need backward compatibility you can use migration plugin.

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
6

Update! Complete answer overhaul for new plugin!

The following plugin has been tested in all major browsers. It makes traditional use of userAgent string to re-equip jQuery.browser only if you're using jQuery version 1.9 or Greater!

It has the traditional jQuery.browser.msie type properties as well as a few new ones, including a .mobile property to help decide if user is on a mobile device.

Note: This is not a suitable replacement for feature testing. If you expect to support a specific feature on a specific device, it's still best to use traditional feature testing

/** jQuery.browser
 * @author J.D. McKinstry (2014)
 * @description Made to replicate older jQuery.browser command in jQuery versions 1.9+
 * @see http://jsfiddle.net/SpYk3/wsqfbe4s/
 *
 * @extends jQuery
 * @namespace jQuery.browser
 * @example jQuery.browser.browser == 'browserNameInLowerCase'
 * @example jQuery.browser.version
 * @example jQuery.browser.mobile @returns BOOLEAN
 * @example jQuery.browser['browserNameInLowerCase']
 * @example jQuery.browser.chrome @returns BOOLEAN
 * @example jQuery.browser.safari @returns BOOLEAN
 * @example jQuery.browser.opera @returns BOOLEAN
 * @example jQuery.browser.msie @returns BOOLEAN
 * @example jQuery.browser.mozilla @returns BOOLEAN
 * @example jQuery.browser.webkit @returns BOOLEAN
 * @example jQuery.browser.ua @returns navigator.userAgent String
 */
;;(function($){var a=$.fn.jquery.split("."),b;for(b in a)a[b]=parseInt(a[b]);if(!$.browser&&(1<a[0]||9<=a[1])){a={browser:void 0,version:void 0,mobile:!1};navigator&&navigator.userAgent&&(a.ua=navigator.userAgent,a.webkit=/WebKit/i.test(a.ua),a.browserArray="MSIE Chrome Opera Kindle Silk BlackBerry PlayBook Android Safari Mozilla Nokia".split(" "),/Sony[^ ]*/i.test(a.ua)?a.mobile="Sony":/RIM Tablet/i.test(a.ua)?a.mobile="RIM Tablet":/BlackBerry/i.test(a.ua)?a.mobile="BlackBerry":/iPhone/i.test(a.ua)?
a.mobile="iPhone":/iPad/i.test(a.ua)?a.mobile="iPad":/iPod/i.test(a.ua)?a.mobile="iPod":/Opera Mini/i.test(a.ua)?a.mobile="Opera Mini":/IEMobile/i.test(a.ua)?a.mobile="IEMobile":/BB[0-9]{1,}; Touch/i.test(a.ua)?a.mobile="BlackBerry":/Nokia/i.test(a.ua)?a.mobile="Nokia":/Android/i.test(a.ua)&&(a.mobile="Android"),/MSIE|Trident/i.test(a.ua)?(a.browser="MSIE",a.version=/MSIE/i.test(navigator.userAgent)&&0<parseFloat(a.ua.split("MSIE")[1].match(/[0-9\.]{1,}/)[0])?parseFloat(a.ua.split("MSIE")[1].match(/[0-9\.]{1,}/)[0]):
"Edge",/Trident/i.test(a.ua)&&/rv:([0-9]{1,}[\.0-9]{0,})/.test(a.ua)&&(a.version=parseFloat(a.ua.match(/rv:([0-9]{1,}[\.0-9]{0,})/)[1].match(/[0-9\.]{1,}/)[0]))):/Chrome/.test(a.ua)?(a.browser="Chrome",a.version=parseFloat(a.ua.split("Chrome/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):/Opera/.test(a.ua)?(a.browser="Opera",a.version=parseFloat(a.ua.split("Version/")[1].match(/[0-9\.]{1,}/)[0])):/Kindle|Silk|KFTT|KFOT|KFJWA|KFJWI|KFSOWI|KFTHWA|KFTHWI|KFAPWA|KFAPWI/i.test(a.ua)?(a.mobile="Kindle",
/Silk/i.test(a.ua)?(a.browser="Silk",a.version=parseFloat(a.ua.split("Silk/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):/Kindle/i.test(a.ua)&&/Version/i.test(a.ua)&&(a.browser="Kindle",a.version=parseFloat(a.ua.split("Version/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0]))):/BlackBerry/.test(a.ua)?(a.browser="BlackBerry",a.version=parseFloat(a.ua.split("/")[1].match(/[0-9\.]{1,}/)[0])):/PlayBook/.test(a.ua)?(a.browser="PlayBook",a.version=parseFloat(a.ua.split("Version/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):
/BB[0-9]{1,}; Touch/.test(a.ua)?(a.browser="Blackberry",a.version=parseFloat(a.ua.split("Version/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):/Android/.test(a.ua)?(a.browser="Android",a.version=parseFloat(a.ua.split("Version/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):/Safari/.test(a.ua)?(a.browser="Safari",a.version=parseFloat(a.ua.split("Version/")[1].split("Safari")[0].match(/[0-9\.]{1,}/)[0])):/Firefox/.test(a.ua)?(a.browser="Mozilla",a.version=parseFloat(a.ua.split("Firefox/")[1].match(/[0-9\.]{1,}/)[0])):
/Nokia/.test(a.ua)&&(a.browser="Nokia",a.version=parseFloat(a.ua.split("Browser")[1].match(/[0-9\.]{1,}/)[0])));if(a.browser)for(var c in a.browserArray)a[a.browserArray[c].toLowerCase()]=a.browser==a.browserArray[c];$.extend(!0,$.browser={},a)}})(jQuery);
/* - - - - - - - - - - - - - - - - - - - */

var b = $.browser;
console.log($.browser);    //    see console, working example of jQuery Plugin
console.log($.browser.chrome);

for (var x in b) {
    if (x != 'init')
        $('<tr />').append(
            $('<th />', { text: x }),
            $('<td />', { text: b[x] })
        ).appendTo($('table'));
}
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: .25em .5em; vertical-align: top; }
th { text-align: right; }

textarea { height: 500px; width: 100%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
  • @micnic it's unminified on my home server and will be on a site in the near future. i'm at work for now, is there an issue you found? – SpYk3HH Jun 02 '15 at 14:17
  • yes, I found an issue, it detects IE9 and IE10 version as 9.06 and 10.06 (IE11 is ok) – micnic Jun 02 '15 at 15:06
  • @micnic yeah, found the issue. was pretty easy to fix. was my former use of `.replace` as opposed to my new, and better use of `.match`. give it a try! I had just c&p'd it to EPPro and did a full text replace. so it should follow through the whole thing – SpYk3HH Jun 02 '15 at 15:42
5

Include jQuery migration plugin along with your jQuery library.

Michael Schmidt
  • 9,090
  • 13
  • 56
  • 80
Kishore
  • 51
  • 1
  • 1
4

Using this:

if (navigator.userAgent.match("MSIE")) {}

Steven.Nguyen
  • 1,034
  • 13
  • 14
3

You can detect the IE browser by this way.

(navigator.userAgent.toLowerCase().indexOf('msie 6') != -1)

you can get reference on this URL: jquery.browser.msie Alternative

1

You can use :

var MSIE = jQuery.support.leadingWhitespace; // This property is not supported by ie 6-8

$(document).ready(function(){

if (MSIE){
    if (navigator.vendor == 'Apple Computer, Inc.'){
        // some code for this navigator
    } else {
       // some code for others browsers
    }

} else {
    // default code

}});
Lucks
  • 11
  • 3
0

Instead of having the whole migration script added, you could simply add the following (extracted from the migration script)

$.uaMatch = function( ua ) {
    ua = ua.toLowerCase();

    var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
        /(msie) ([\w.]+)/.exec( ua ) ||
        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
        [];

    return {
        browser: match[ 1 ] || "",
        version: match[ 2 ] || "0"
    };
};

and then use it like so

$.uaMatch(navigator.userAgent)
Johan
  • 8,068
  • 1
  • 33
  • 46
0

I had this problem as well. We were using two versions of Jquery (1.11.3 and 1.8.3), one of which was causing this issue. I found a lightbox_me.js release that worked on both versions:

http://buckwilson.me/lightboxme/

It was just an easy replacement of an old file.

War Gravy
  • 1,543
  • 3
  • 20
  • 32