In the last post we looked at feature detection with Modernizr. Before moving forward, let me answer a few questions that came up.
First, you can build a custom Modernizr download containing only the tests you care about when you visit http://www.modernizr.com/download/. If you don't care about the geolocation APIs, then don't check the geolocation checkbox. The script file you download will be smaller, and more importantly there are fewer tests to run when the script hits the browser. Chances are good you will only care about a handful of the possible tests.
Secondly, Modernizr doesn't add any missing features to a browser. Modernizr only tests to see if specific features are available. The single exception is that Modernizr does create HTML 5 elements for older versions of IE. We looked at this capability in the first post of this series. Everything else is just a test. Modernizer can tell you if the geolocation API is available, or if it isn't. If the API is available you can use it. If the API is not available then you have a decision to make. Do you gracefully degrade the page and hide content that requires the user's location? Or, do you enter the world of polyfills and web shims?
Polyfills are spackling paste for web browsers. They fill the holes left behind when a browser doesn't implement a feature. There are dozen of polyfills available, and some are more elaborate than others. Ideally a polyfill API will mimic the real HTML 5 API so you can use a single codebase for all browsers, but this ideal scenario is not always possible.
Let's say, for example, that you want to use the geolocation API to display a user's current latitude and longitude. You might use something like the following:
navigator.geolocation.getCurrentPosition( onGeoSuccess, onGeoError); function onGeoSuccess(position) { var display = $("#position").tmpl(position.coords); $("body").append(display); } function onGeoError(e) { $("body").append(e.message); }
And use the following template to display the result:
<script id="position" type="text/x-tmpl"> <div> Latitude: ${latitude} Longitude: ${longitude} </div> </script>
Now imagine someone with a new Kindle Fire comes to your website. The Fire's browser (Silk) doesn't support the geolocation API. You could discover this if you just ask Modernizr.
if (!Modernizr.geolocation) { // }
To support geolocation on browsers like Silk, you could use the Webshims Lib by Alexander Farkas. The WebShims lib includes scripts to polyfill not just geolocation features, but also ECMAScript 5 features, new HTML 5 inputs, canvas, and more. You just need to load the polyfiller.js bootstrapping code (which requires jQuery and Modernizr's script loader).
<script src="jquery.js"></script> <script src="modernizr-geo.js"></script> <script src="polyfiller.js"></script> <script> $.webshims.polyfill(); </script>
The beauty of the geolocation polyfill is how the script lets you use the same API you would use when a browser natively implements geolocation – no code has to change! Of course, not all polyfills are as easy, but hopefully we won't have to live with them for more than a few more years. Or 5. Or 10 ...