A polyfill is a piece of code that provides a fallback if a certain feature doesn’t exist within that browser’s JS engine. Polyfills usually follow a pattern. First, they check to see if the function they implement exists, and then we only write our fallback implementation if we have to.
There are multiple polyfills out there for mutliple functions. The website HTML5 Please is very useful for finding polyfills to do a particular job.
Now, lets get to our own
implementation. Today we’ll be implementing
Local and session storage are a great way to store data without
resorting to cookies. IE8 supported
localStorage
and sessionStorage
so you may not need a polyfill. If you do,
Remy's is a piece of cake to implement and use.
This is a simple
key/value store, so if you want to store complex data use JSON.parse(str) and JSON.stringify(obj)
on your way in and out. There is also no way to know if you exceeded the
storage cross-browser, so wrap your store commands in try/catch. Up to 2.5MB is
safe to use.
As part of
keeping things simple, localStorage has a synchronous API that runs on the main
UI thread in browsers; as a consequence of that, a race
condition can occur if a user has the same site open in multiple windows or
tabs running as separate processes. For many applications, that’s never really
a problem in practice. But it can cause data corruption—so applications where
it’s important to try to ensure that absolutely no data corruption can occur
should instead use a more robust storage mechanism such as IndexedDB.
Due to the
shortcomings of localStorage, there are calls to
stop advocating for and building examples that use it.
Recommended
polyfills:
Modernizr
is a JavaScript library that detects which HTML5 and CSS3 features your
visitor’s browser supports. In detecting feature support, it allows developers
to test for some of the new technologies and then provide fallbacks for
browsers that do not support them. This is called feature detection and
is much more efficient than browser sniffing.
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<title>Hello Modernizr</title>
<script src="modernizr.js"></script>
</head>
<body>
</body>
</html>
You can see
in the code above that you need a modernizr.js file. You have to build and download this yourself
by choosing the features you want to detect.
Do this by choosing the ‘Local Storage' option
in Figure 1 and click on BUILD, then select the necessary options in Figure 2.
Old Modernizr creates a global Modernizr JavaScript object, which allows us to query different properties
of that object to perform feature detection by calling Modernizr.<featurename>.A
lot has changed since the last version of Modernizr. There no longer is a
single, base
modernizr.js
file. Instead, just head over to the Download
page as you could have previously, and select the features you want to use in
your project. This way we can provide the smallest file possible, which means a
faster website for you. Once you have done that, just hit the Build
button and you’ve got your own custom build of Modernizr.
Command Line Config
Since 3.0,
Modernizr also ships its build system as a node
module on npm. That means that you can quickly
create multiple builds of Modernizr for different projects, without even having
to open a new browser tab.
Once you have npm installed,
you can install the Modernizr command line tool by running
npm install -g modernizr
Now you are ready
to get your start making your custom build! You can download the configuration
file from the build menu (under "Command Line Config"). This will
give you a JSON file that
you will give to the Modernizr module to make your custom build.
modernizr -c modernizr-config.json
Note
that you will need to give the command line config the file path to the
configuration you downloaded from the site. In the above example, we are
running the modernizr command from the same folder that we downloaded the modernizr-config.json
file to.
Using Modernizr with JavaScript
The Modernizr object
Modernizr keeps track of the results of all of it's feature detections via theModernizr
object. That means that for each test, a
corresponding property will be added. You just have to test for truthiness
in your code to figure out what you want to do
CSS
.no-localstorage .box { color: red; }
.localstorage .box { color: green; }
JS
if (Modernizr.localstorage) {
// supported
} else {
// not-supported
}
In the examples above, you’ve seen the simplest way to detect a browser feature. What if you wanted
to detect a feature and use a polyfill to make the browser perform better?
You can do this with YepNope.
YepNope is a
conditional loader, which means it will only load the scripts that are needed
by the browser. And it’s built into Modernizr, so you don’t have to worry about
downloading and linking to another JavaScript file.<script src='localStorage.js'></
The problem with this approach is that all browsers will download this script. That’s unnecessary and should be avoided where possible. You could arguably wrap the <script> element in conditional comments, but if you can keep the files out of the markup altogether, then you should. You can do this using Modernizr.load(). Modernizr has YepNope built into it, so you can easily test for a feature and then supply a polyfill.
You should note that .load() is not included in the development file by default. You need to include it and build it yourself.
The basic use of the .load() function allows you to test for a feature and ask whether it’s true (yep) or false (nope). In this example, Modernizr tests for localStorage support, and if the feature doesn’t exist, then it loads localStorage:
<html>
<head>
<script src='Modernizr.js'></script>
</head>
<body>
<script>
Modernizr.load({
test : Modernizr.localStorage,
nope:'localStorage.js',
complete:function(){
localStorage.setItem('key',' value');
}
});
</script>
</body>
</html>
Here’s a more
practical example that detects the support of <input type="date">. If it isn’t supported, it loads in two
jQuery files and a CSS file to generate a styled date picker:<script src="modernizr.js"></script>
<script>Modernizr.load({
test: Modernizr.inputtypes.date,
nope: ['http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js', 'jquery-ui.css'],
complete: function () {
$('input[type=date]').datepicker({
dateFormat: 'yy-mm-dd'
});
}
});
</script>
This test looks for <input type="date"> support. When it fails,
it loads in the two external jQuery JavaScript files and a local CSS file.
(Our tests suggest that the CSS file needs to be local.) Once it’s done that (i.e., on complete),
it then calls the plugin for each <input type="date"> in the DOM. In most browsers,
the jQuery will be loaded (Figure 6), but in Opera, the files aren’t loaded because it has a native
calendar control (Figure 7):
Figure 3: jQuery date picker widget in Firefox
Figure 4: Native date picker widget in Opera
As a conclusion, Modernizr is
a powerful feature detection library. It allows you to check whether a browser
supports various features and, depending on what you want to achieve, lets you
use a polyfill. This article looked at how to generate a Modernizr JavaScript
file and examined two different ways of using Modernizr: directly using the
Modernizr object (Modernizr.<featurename>) and then using the
built-in YepNope.
No comments:
Post a Comment