parentNode.org

The building blocks of a solid frontend.

Javascript Browser Detection Revisited

Posted in Browsers, JavaScript by Munter on the July 14th, 2006

You’ve all seen them before. Javascript browser detection scripts. There are extremely large and ugly ones out there, ignoring the fact that browser detection in itself is an ugly thing having to resolve to. Our suggestion is based on not trusting the user agent string delivered by the browser. Instead we use a combination of object detection and bad voodoo to be 100% sure what browser and what version is served. Updated for IE7!

Do we really need this?

Hopefully not. In most circumstances you can secure yourself from doing stuff to a browser that it doesnt support, simply by checking if method X or object Y is available before you use it. However, the better you get at scripting, and the more crossbrowser compatibility you have to have, the more boundaries get touched or crossed. You will end up with some stupid differences, like IE’s different implementation of what mousebutton was pressed, or Gecko firing a mouseover event when the mouse wasn’t actually moved, but the position of the element below it was.

So we agree that browser detection is only for far-out stuff, and it’s still ugly. But sometimes you have do to what you can to get the job done. Now, especially when writing stuff that pushes the limits of browser capability, you will encounter people that think they are clever with their browser setup. People writing all sorts of wierd stuff in their user agent string, or just browsers like Opera 8, that had to fake being Internet Explorer because MS was deliberately sending out wrong styles for non-IE browsers on MSN.

If the user agent string can’t be trusted, we need to go deeper. So we decided to use object detection, and for IE a little spicy technique called Conditional Compilation, something only available in JScript.

The Code

function detectBrowser() {
    var BO = new Object();
    BO["ie"]        = false /*@cc_on || true @*/;
    BO["ie4"]       = BO["ie"] && (document.getElementById == null);
    BO["ie5"]       = BO["ie"] && (document.namespaces == null) && (!BO["ie4"]);
    BO["ie6"]       = BO["ie"] && (document.implementation != null) && (document.implementation.hasFeature != null);
    BO["ie55"]      = BO["ie"] && (document.namespaces != null) && (!BO["ie6"]);
    /*@cc_on
    BO["ie7"]       = @_jscript_version == '5.7';
    @*/
    BO["ns4"]       = !BO["ie"] &&  (document.layers != null) &&  (window.confirm != null) && (document.createElement == null);
    BO["opera"]     = (self.opera != null);
    BO["gecko"]     = (document.getBoxObjectFor != null);
    BO["khtml"]     = (navigator.vendor == "KDE");
    BO["konq"]      = ((navigator.vendor == 'KDE') || (document.childNodes) && (!document.all) && (!navigator.taintEnabled));
    BO["safari"]    = (document.childNodes) && (!document.all) && (!navigator.taintEnabled) && (!navigator.accentColorName);
    BO["safari1.2"] = (parseInt(0).toFixed == null) && (BO["safari"] && (window.XMLHttpRequest != null));
    BO["safari2.0"] = (parseInt(0).toFixed != null) && BO["safari"] && !BO["safari1.2"];
    BO["safari1.1"] = BO["safari"] && !BO["safari1.2"] && !BO["safari2.0"];
    return BO;
}

var BO = new detectBrowser();

The Explanation

There isn’t much to explain really. The function returns an object with boolean properties like BO.ie, BO.gecko etc. We suggest doing this check only once and storing the object where ever you might need it for later reference.

To check for IE we use a JScript only construct called Conditional Compilation, which sets BO.ie to true, but only for IE of course.

The other stuff does various object and method detections based on our knowledge of different implementations in different versions. This list is of course not complete, so if you have any additions that follow the same detection method please comment on this article. This is just what we have been needing so far.

5 Responses to 'Javascript Browser Detection Revisited'

Subscribe to comments with RSS or TrackBack to 'Javascript Browser Detection Revisited'.


  1. on July 23rd, 2006 at 4:18 pm

    Very nice, only thing one could comment about is the lag of IE3 support. But as many of our readers would agree there is close to no users using IE3 anymore.

  2. Munter said,

    on January 31st, 2007 at 1:43 pm

    Just added IE7 support, since that was lacking.

    That work by checking the JScript engine version, since that was updated for IE7.

    I am not sure if this will work on machines with multiple Ie versions installed. If someone can check that it would be nice.

  3. WileE said,

    on August 16th, 2007 at 1:59 pm

    Great articel!

    I use another way to identify IE 7 by checking the window.XMLHttpRequest - just in case anybody is interested:
    BO[”ie7″] = (BO[”ie”] && document.implementation != null && document.compatMode != null && window.XMLHttpRequest != null)

  4. tony said,

    on September 7th, 2007 at 3:55 pm

    IE3 support? what?! are you serious?

    Most web apps today won’t support less than IE6, and even then, only grudgingly.

  5. Aaron Schinkowitch said,

    on January 8th, 2008 at 8:17 am

    Using the code above, I was getting a false positive for ie6 on ie7 until I added a && window.XMLHttpRequest == null to the check for ie6.

Leave a Reply