Feature Detection vs Browser Detection

JavaScript Feature and Browser DetectionWe've all heard time and time again that when you're trying to determine the JavaScript capabilities of a browser you should avoid user agent string parsing like a horrible plague and instead put your trust in a little thing called feature detection. But why should we? What's so bad about relying on user agent strings? Also, how do I even use feature detection anyway? Read on and you'll find the answer to all of these questions.

Browser Detection via User Agent Strings

A long time ago, on a planet so similar to ours you'd think that it actually was ours, creatures known as humans would use Java Script to parse user agent strings to determine the browser that a user was browsing their site with. Ok, ok, it wasn't that long ago (in fact countless people still do this) and it actually was this planet that we call Earth.

Browser detection is generally done by reading a property known as navigator.userAgent that contains a string with a lot of information about the browser that is currently being used to visit the page. This can – and often is – be used quite reliably to actually determine the browser and version being used but it has several caveats in relation to using it in order to make determinations about how your code works.

  1. The userAgent string can be faked pretty easily, and while this reason is quoted quite often, it seems the least relevant because the only people that would fake that string are people who know what they are doing and would probably expect that changing that value might create problems.
  2. You cannot know which features future browsers will provide, so the moment a browser is developed that changes the features in a way that you don't predict, your script is broken.
  3. You have to know which browsers support which features. Sometimes this is very simple when it comes to a feature that everyone knows about, but it's difficult to use when you need to keep track of several features.

Feature Detection

Feature detection is a much more reliable to determine if you can use a feature because it goes straight to the feature and asks it whether it exists. Well, it's not literally like that, but it seems like it. Feature detection utilizes the fact that if you try to access a property of an object that doesn't exist, it will be undefined. So if the property or function that you need isn't undefined, then you're free to use it, otherwise you can check alternate properties to see if they're available instead.

If you need to check whether a feature exists directly in the global scope, make sure you check for it as a property of window (e.g. window.propertyName) because if a property doesn't exist when you try to check it without the window prefix, you'll end up with a ReferenceError. Confused? Here's an example, checking for XHR capabilities.

// Does the browser use the standard XHR?
if ( window.XMLHttpRequest )
{
    xhr = new XMLHttpRequest();
}
// If the browser isn't using the standard, let's
// check for the alternative
else if ( window.ActiveXObject )
{
    xhr = new ActiveXObject( "Microsoft.XMLHTTP" );
}

// Here, we're not using window in front. If
// XMLHttpRequest doesn't exist, this will
// result in an error instead of moving on to
// the else if
if ( XMLHttpRequest )
{
    xhr = new XMLHttpRequest();
}
// This will never run because the top will either
// be true or will be an error.
else if ( ActiveXObject )
{
    xhr = new ActiveXObject( "Microsoft.XMLHTTP" );
}

Other than the reasons listed above as reasons not to use user agent parsing, there's one additional reason to use feature detection instead: it tests for the features that you want to use rather than testing for a browser. That just makes a lot more sense to me.

Feature Detection FTW

So as you can see, feature detection is simple and sensible. Browser detection on the other hand is full holes. I can see browser detection working for use cases where you actually need to know which browser is being used, but using it to determine which features are implemented by the browser isn't a great idea. That'll finish this up. I hope most of you already knew most of this, but I'm sure there are plenty of people out there who learned from this. God Bless and Happy Coding!

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.