Sunday, May 14, 2017

Using Polyfill with Modernizr



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.


First, you need an HTML document:

<!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 the Modernizr 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.



You’ll generally want a fallback for non-supporting IE8 and below. The usual way of doing this would be to link to a JavaScript polyfill, such as localStorage in your HTML:

<script src='localStorage.js'></script>

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