jQuery 1.9 browser detection

42,791

Solution 1

You should add a little sanity check to your popstate handler, and make sure that it doesn't do anything expensive if you "pop" into the same state you started in. Then you can not care about the browser, and instead just call your popstate on document ready:

$(function(){
    $(window).on('popstate', popState);

    // call popstate on document ready
    $(popstate);
});

The answer suggesting you paste the code from $.browser back into your environment is way overkill to support a bad practice. You can feature detect 99% of the things you need to. Almost every use of $.browser is a dangerous. There are almost always ways to detect that.

The JavaScript community has been against browser sniffing for a long time. Here is a post from 2009 telling us why it's a bad idea. There are many others.

I beg you not to copy $.browser back into your code, the jQuery team decided to kill it for a reason.

Solution 2

Here is a fast way to solve this problem. Add this line of codes to your jQuery-1.9.js and replace $.browser with jQuery.browser

jQuery.browser = {};
jQuery.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit    /.test(navigator.userAgent.toLowerCase());
jQuery.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
jQuery.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
jQuery.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());

here

Solution 3

I guess putting this code would do the trick for you. Don't forget to make changes if you need as per your requirement.

var matched, browser;

// Use of jQuery.browser is frowned upon.
// More details: http://api.jquery.com/jQuery.browser
// jQuery.uaMatch maintained for back-compat
jQuery.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"
    };
};

matched = jQuery.uaMatch( navigator.userAgent );
browser = {};

if ( matched.browser ) {
    browser[ matched.browser ] = true;
    browser.version = matched.version;
}

// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
    browser.webkit = true;
} else if ( browser.webkit ) {
    browser.safari = true;
}

jQuery.browser = browser;

For your information - jQuery Docs

We recommend against using this property; please try to use feature detection instead (see jQuery.support). jQuery.browser may be moved to a plugin in a future release of jQuery.

jQuery.browser

jQuery.support

Share:
42,791
bevacqua
Author by

bevacqua

Principal Software Engineer at Elastic, helping lead the Elastic Cloud UI team. ● Pre-IPO employee at Elastic, helping drive key initiatives in Elastic Cloud ● Authored 3 books on JavaScript/Node.js application architecture ● Organized first ever Node.js conference in Buenos Aires (NodeConf Argentina) ● Author dragula drag &amp; drop library (20k stars) and prolific open source contributor ● Wrote my own MVC frameworks, clones of async, jQuery, Markdown parsers, and more (purely as a way of learning) ● Grew newsletter on JavaScript to 17k subscribers (Pony Foo Weekly) ● 40k karma on StackOverflow 😅 ● Avid reader Published author of several software development books: Mastering Modular JavaScript (O'Reilly, 2018), Practical Modern JavaScript (O'Reilly, 2017), and JavaScript Application Design (Manning, 2015). Nicolás has vast experience in tackling challenging technical problems, as well as in helping manage teams, driving technical innovation, collaborating across areas, and sharing his applied learning.

Updated on July 05, 2022

Comments

  • bevacqua
    bevacqua almost 2 years

    In earlier versions, I used to test if I should be triggering popstate manually on page load, because Chrome triggers it right after load, and Firefox and IE do not.

    if ($.browser.mozilla || $.browser.msie) {
        $(window).trigger('popstate');
    }
    

    Now that they dropped the browser object in 1.9, how should I test for these browsers? Or how do I figure if I need to popstate on page load or not?

    The code is:

    $(function(){
        $(window).on('popstate', popState);
    
        // manual trigger loads template by URL in FF/IE.
        if ($.browser.mozilla || $.browser.msie) {
           $(window).trigger('popstate');
        }
    });
    

    Update

    Went for this:

        function popState(e){
            var initial = e.originalEvent === undefined || e.originalEvent.state === null;
            if(!initial){
                activateRoute({
                    key: e.originalEvent.state.key,
                    settings: e.originalEvent.state.settings
                },'replace');
            }
        }
    
        function init(){
            $(window).on('popstate', popState);
    
            $(function(){
                var route = getRoute(document.location.pathname);
                activateRoute(route, 'replace');
            });
        }
    
  • gnarf
    gnarf over 11 years
    Plugging the code from browser back in isn't the answer... Not sniffing is. Also, please attribute that giant chunk of code, or link to it in the github repo. That is licensed code.
  • bevacqua
    bevacqua over 11 years
    I didn't, I actually did something similar to what you proposed. My updated question has the solution I arrived at.
  • gnarf
    gnarf over 11 years
    Also, I would suggest posting an answer with your eventual solution rather than editing your question. It's not "bad form" at all, it's actually encouraged.
  • Langdon
    Langdon over 11 years
    I appreciate the last line of this answer. I was about to do that.
  • numediaweb
    numediaweb over 10 years
    that's true; "$.browser" is dead. jquery internally uses feature detection through "jQuery.support" but they strongly recommend the use of an external library such as Modernizr instead.