Question

How should browser detection be done now that jQuery 1.3 has deprecated (and I'm assuming removed in a future version) $.browser.msie and similar?

I have used this a lot for determining which browser we are in for CSS fixes for pretty much every browser, such as:

$.browser.opera
$.browser.safari
$.browser.mozilla

... well I think that's all of them :)

The places where I use it, I'm not sure what browser issue is causing the problem, because a lot of times I'm just trying to fix a 1 px difference in a browser.

Edit: With the new jQuery functionality, there is no way to determine if you are in IE6 or IE7. How should one determine this now?

Was it helpful?

Solution

I was facing something similar, there's no $.support.png (p.ej.), so I need to use the $.browser.version yet, maybe we can just keep asking for more $.support.XXXX properties, as much as needed.

OTHER TIPS

Yes, the browser detection has been deprecated, but the deprecated properties probably won't be removed from jQuery anytime soon. And when they will be removed, if you still absolutely need to do browser detection, you can add the same functionality easily with a small, simple plugin.

So, my answer is to do nothing about it, for now :)

edit: I'll even provide you with a plugin to use in the future (not tested, copy-pasted from jquery source):

(function($) {
    var userAgent = navigator.userAgent.toLowerCase();

    $.browser = {
        version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
        safari: /webkit/.test( userAgent ),
        opera: /opera/.test( userAgent ),
        msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
        mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
    };

})(jQuery);

.browser has been deprecated in favour of .support. More information over here: jquery.support What this essentially means is that instead of using browser sniffing, jquery now does feature support detection and allows for much finer grained control over what the browser can do.

From the description:

Added in jQuery 1.3 A collection of properties that represent the presence of different browser features or bugs.

jQuery comes with a number of properties included, you should feel free to add your own. Many of these properties are rather low-level so it's doubtful that they'll be useful in general day-to-day development, but mostly used by plugin and core developers.

The values of all the support properties are determined using feature detection (and do not use any form of browser sniffing)

feature support sounds a good idea, BUT it will only work as is intended when it supports all possible "bugs". Like the first commenter, there is no $support.png, or a $support.stepping, or a $support.peekaboo, or a, oh, the list goes on. The problem with this is that some code to make one browser compliant will inevitable end up being executed by a browser that does not need it.

Browser detection isn't deprecated in jQuery. Doc page for jQuery.browser, which states:

We recommend against using this property, please try to use feature detection instead (see jQuery.support).

Deprecation means "slated for future removal." This advice about sniffing for capabilities rather than user agents is just good general advice, and not specific to jQuery. All they're saying is they're making it easier to do the right thing.

There's always going to be a need for user agent sniffing however. Unless jQuery.support is updated daily by an army of developers, there's just no way it can keep up with every bug and every feature in every minor point version of every browser.

I think the confusion about this arose from the fact that, internally, jQuery no longer does browser sniffing. But the utility API jQuery.browser will continue to exist.

function browserLessThanIE7(){
   return (/MSIE ((5\\.5)|6)/.test(navigator.userAgent) && navigator.platform == "Win32");
}

Could also work fine... This one checks for version 5, 5.5 and 6.

@Nate: change (5\.5)|6 into 7 and it checks for version 7.

I say reverse engineer it from jQuery 1.2's codebase.

See this section of the code:

jQuery.browser = {
    version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
    safari: /webkit/.test( userAgent ),
   opera: /opera/.test( userAgent ),
  msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
  mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

Respect the GPL and MIT licenses and learn from the code. Don't copy and paste.

Or specifically for smelling out IE6. You could do:

function IsThisBrowserIE6() {
    return ((window.XMLHttpRequest == undefined) && (ActiveXObject != undefined))
}

Feature detection sounds all fine and dandy, but when I am writing some code that doesn't work in a certain browser, the quickest method is browser detection.

Horizontally centering an element using auto margins works for all browsers except IE. What feature do I test for? I have no idea. But I do know which browser it doesn't work in.

I can see why feature detection would be useful in certain situations eg. if a browser is in quirks/strict mode. The best compromise would be to utilise both methods.

In light of this "We recommend against using this property, please try to use feature detection instead" should be removed from the jQuery.browser documentation page. It is misleading.

Why couldn't jquery.browser be re-written to use jquery.support internally to determine the browser based on features (perhaps supplemented with current methods from jquery.browser where needed), to provide a convenient means to select for browser family and version, while perhaps being more reliable than today's jquery.browser?

jQuery 1.3 has replaced browser testing.

Frankly I'm surprised how often Web developers are concerned about what browser their site is running in. In 10+ years of Web development I can think of a handful of cases where I've cared let alone bothered to do anything different. The most common reason has been that the named font sizes differ significantly between Firefox and IE (font-size: large is a lot larger in IE than FF) so I have used an IEfix.css file to correct that.

Perhaps you should look at What is better: CSS hacks or browser detection? for a more thorough discussion on the topic.

The long and short of it is you should care if a feature is supported or not, not which browser it is.

It's hard to say anything more without knowing why you care if it's IE because you'll probably find there's a much better solution to doing what you're doing.

Try the GeckoFix script at http://code.labor8.eu/geckoFix , it detects the Firefox lower than 3.0 so you can customize it how you want (i.e. by adding more rules to it like detecting Firefox 2, Firefox 3, Opera and Safari). I think it could be what you're looking for. To check user agent just type in your address bar javascript:alert(navigator.userAgent) and find some specific characters you'll need to type in script.

I've got a piece of Javascript that runs fine in Mozilla and Webkit browsers, as well as IE8. However, in 6 and 7 it breaks. This has nothing to do with the CSS, nor poor Javascript, but the crappy supports of IE<8.

I can see where people are coming from about checking for "features" as opposed to browser sniffing, however, the features that sniffing is available for are not relevant to the breaking code, so then what is the difference between browser sniffing and feature sniffing until ALL features are available in the $.support object?

I'd like to point out that navigator.userAgent isn't very trustworthy, in the sense that it's easily modifiable and might not represent the actual browser viewing the page. This might be one of the reasons $.browser was deprecated in the first place.

But for the sake of the question, let's assume browser detection is absolutely needed.

I ran into this very cool snippet by James Padolsey, which actually differentiates between Internet Explorers by using conditional comments.

I've compiled a small piece of code with above snippet and some code from yepnope.js:

(function(window, doc) {
    window.detector = window.detector || (function() {
        var undef,
            docElement = doc.documentElement,       
            v = 3,
            div = document.createElement('div'),
            all = div.getElementsByTagName('i'),
            isGecko = ( 'MozAppearance' in docElement.style ),
            isGeckoLTE18 = isGecko && !! doc.createRange().compareNode,
            isOpera = !! ( window.opera && toString.call( window.opera ) == '[object Opera]' ),
            isWebkit = ( 'webkitAppearance' in docElement.style ),
            isNewerWebkit = isWebkit && 'async' in doc.createElement('script');

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

            return {
                isGecko: isGecko,
                isGeckoLTE18: isGeckoLTE18,
                isGeckoGT18: isGecko && ! isGeckoLTE18,
                isOpera: isOpera,
                isWebkit: isWebkit,
                isNewerWebkit: isWebkit && 'async' in doc.createElement('script'),
                isIE: ( v > 4 ),
                ieVersion: ( v > 4 ? v : undef )
            };
    }());
}(window, document));

This differentiates between browsers by their capabilities.

Only problems are, I currently have no way of telling between Safari and Chrome (both Webkit browsers), and between the versions of the Gecko, Webkit and Opera browsers themselves.

I know it's not perfect, but it's a slight improvement over navigator.userAgent.

This may not be the cleanest way for IE 6 but it certainly works and is easy to understand:

$(document).ready(function() {
    ie6catch = $.browser.msie + $.browser.version;
    if (ie6catch.indexOf("true6") == -1) {
        alert("This is not Internet Explorer 6");
    }
});

What would be a good idea is to add browsers as a class to the body tag for css. Not sure if this works because I don't run windows and I have a powerPC but it should put a class of .ie6 to all internet explorers 6-9, not very helpful. Use mooModernizr for everything else.

if (Browser.Engine.trident) {

    var IEbrowser = $('body');

    IEbrowser.addClass('ie');

}​
var browser = {
        chrome: false,
        mozilla: false,
        opera: false,
        msie: false,
        safari: false
    };
    var sBrowser, sUsrAg = navigator.userAgent;
    if(sUsrAg.indexOf("Chrome") > -1) {
        browser.chrome = true;
    } else if (sUsrAg.indexOf("Safari") > -1) {
        browser.safari = true;
    } else if (sUsrAg.indexOf("Opera") > -1) {
        browser.opera = true;
    } else if (sUsrAg.indexOf("Firefox") > -1) {
        browser.mozilla = true;
    } else if (sUsrAg.indexOf("MSIE") > -1) {
        browser.msie = true;
    }
console.log(browser.msie);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top