3

Possible Duplicate:
Browser detection versus feature detection

I have been reading about feature detection (using Google/Wikipedia/Docs) but don't quite get a grip of it. Some questions pop up

  1. Why is Feature Detection needed. Can't we just detect the browser and write code for it?
  2. Different ways to do feature detection. Best of them all?
  3. Can you give me a practical real world example where Feature Detection works. How do we handle old browsers and how to replicate the same feature in them>
Community
  • 1
  • 1
Tom Hodder
  • 101
  • 4
  • **2:** There aren't multiple ways to do feature detection. Just one: `if ( featureExists ) { /* use feature */ } else { /* fallback solution */ }`. – Šime Vidas Nov 06 '12 at 16:27
  • http://msdn.microsoft.com/en-us/magazine/hh475813.aspx – Robert Harvey Nov 06 '12 at 16:28
  • @ŠimeVidas - there are. you can't really check for CSS features this way. – Knaģis Nov 06 '12 at 16:32
  • @Knaģis There are? Could you elaborate? Which are they? – Šime Vidas Nov 06 '12 at 16:35
  • Why is this tagged `jquery`?! – T.J. Crowder Nov 06 '12 at 16:36
  • @ŠimeVidas - how would you use your approach to determine if the browser supports 'max-width' CSS property? – Knaģis Nov 06 '12 at 16:41
  • @Knaģis: Not everything can be feature detected, but the vast majority of things can be. I suspect you could feature-detect `max-width` by creating an element with `position: absolute; left: -10000px; max-width: 100px; font-size: 12pt`, putting 100 `M`s in it, and measuring its actual width. If it's more than 100, the browser probably doesn't support it. But I haven't actually tried that specific example. *Edit*: Yeah, that seems to work: http://jsbin.com/izeteq/1 (that is **not** a rigorous detection script). – T.J. Crowder Nov 06 '12 at 16:46
  • 1
    @Knaģis `if ( typeof document.body.style.maxWidth !== 'undefined' ) { ...`. My point is that feature-detection by design involves an if-statement. Feature detection means `if ( featureExists ) { ...`, there is no other way to do feature detection. – Šime Vidas Nov 06 '12 at 16:49
  • @ŠimeVidas: Oh, if you want to do it [the *easy* way](http://jsbin.com/izeteq/2)... ;-O – T.J. Crowder Nov 06 '12 at 16:50
  • @T.J.Crowder I just did a Google-search and found that solution (on css-tricks.com). `:)` – Šime Vidas Nov 06 '12 at 16:53

3 Answers3

4

Why is Feature Detection needed. Can't we just detect the browser and write code for it?

No, very quickly your list of what each browser does gets out of date, and it will by its very nature be incomplete. (Does the blackberry browser from three years ago support placeholder text in inputs? I have no idea, nor do I need to care.) For example, it used to be that IE didn't have addEventListener. Now it does. If you start detecting all the way down to the browser version level, then what do you do when new versions come out? It's a maintenance nightmare.

Different ways to do feature detection. Best of them all?

There is no single feature detection, it depends on the feature. You can find a great list of feature detections on this page. There are also libraries like Modernizr that will do the feature-detection for you.

Can you give me a practical real world example where Feature Detection works. How do we handle old browsers and how to replicate the same feature in them>

Sure. I gave you two above, let's dig into them a bit (in reverse order).

addEventListener: This is a common thing to see in code that doesn't use a library like jQuery, YUI, and the like:

if (elm.addEventListener) {
    // Standard
    elm.addEventListener("click", myClickHandler, false);
}
else if (elm.attachEvent) {
    // IE fallback
    elm.attachEvent("onclick", myClickHandler);
}

The great thing about the code above is that when IE9 came out and had addEventListener (in standards mode), code just worked. No need to update a database to say "IE9 has it now."

Or there's placeholder text in input fields, e.g.:

<input type="text" name="firstName" placeholder="First name">

When browsers don't support the placeholder text, they don't have the placeholder property on elements; when they do, they do. So this feature-detects whether the browser supports placeholders:

if ('placeholder' in document.createElement('input')) {
    // Supports the placeholders
}
else {
    // Doesn't, need to do something
}

If it doesn't, you might hook up code to do it yourself. I do that in my place5 plug-in, which is a polyfill for this functionality.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • If you have a hard time with JSLint complaining about the use of `in` for property checks, you can resort to wrapping this check inside an `eval()` (if you've already told JSLint to allow it) or `new Function (...)`. – Ates Goral Feb 24 '13 at 15:38
0
  1. Because browsers might fake their identity. Also because you can't ever know about the features of all possible browsers.
  2. Depends on the feature. If it is a JavaScript method, you usually just check it like this: if (window.XMLHttpRequest) { alert('it supports the XML HTTP requests!'); }. Different features might require different methods how to check them.
  3. With the same example as before - if the check returns false you would fall back on creating ActiveX objects (if supported - it is on older IE versions). Or you might show a message to the user explaining that they will not be able to do certain things in your application.
Knaģis
  • 20,827
  • 7
  • 66
  • 80
0

Some answers, but open for discussion as usual :)

1) To answer this, simply think about how many different browsers and their versions you have in the wild... you would need to write a different piece of code for each if you want to support as many possible browsers... and with mobile browsing, the numbers add up. Having the ability to "detect" a feature will allow you to write only 2 pieces of code, one for browsers with that feature enabled and one for the the others.

2) This is subjective of course. I use Modernizr

3) Look at the features that Modernizr can detect and you will see. For example if you want to enable geolocation client side the best way would be to use a feature detection library rather than keeping your own database of browser specific code (this ties up with question 1). Usually, to cover for feature not implemented you can write your own code in an if-then-else or use a so-called poly-fill, you can read about it here. Basically they are pieces of code that implements functionality not present in older browsers. The beauty is that they are completely transparent, you just use them and don't care if they use the real implementation or fall back on the workaround. The example for the sessionStorage is worth reading.

Tallmaris
  • 7,605
  • 3
  • 28
  • 58