JavaScript libraries are collections of prewritten scripts that aim to reduce the cost of developing applications, and in the past few years, their number has exploded—to the point where you will rarely work on a large project where no libraries are used. From light single-purpose libraries to extensive frameworks, the range is truly wondrous. Whatever you want to do with JavaScript, the odds are good that someone has already written a library for it.
At times writing your own scripts from scratch is the best approach, especially if you don’t want the overhead of some libraries’ large file size. But when working on large teams—when having everyone work to the same standard is advantageous—or when you need to get something into production quickly or for many other reasons, a library is the way to go.
Here I briefly introduce four JavaScript libraries that are useful for front-end developers. Bear in mind that I am barely scraping the surface of what’s available, and just about every developer you talk to will have his or her own favorite (and probably won’t be shy about telling you why it’s superior).
To use each library, in most cases you only have to download or link to a copy of the library and place any code that relies on the library in subsequent files. Remember the warning about using the async attribute in this case. Where installation is more complicated, each library’s documentation will have full instructions.
Using JavaScript libraries can add significant weight to your page and adversely affect loading times. Think carefully before you use them, especially if you’re building sites that may be accessed by visitors on mobile devices, where performance can be a major issue.
I would say almost certainly you have heard of jQuery, as it has quickly become a de facto standard for working on the Web. In August 2012, it was estimated that it’s used on some 50 percent of the top 1 million websites. If you’re comfortable with jQuery and happy that you know all about what it does, you can skip this section. For everybody else, I provide a short overview.
jQuery is a JavaScript framework that simplifies the way you write scripts, abstracting common functions and providing a unified experience across all browsers. It works by creating a set of methods that require simple arguments from the author but perform some quite complex tasks. Here’s a simple example, which I’ll talk through in a second:
$(document).ready(function () {
$('h1').addClass('foo');
});
The first line is required to use jQuery; it acts basically like the DOMContentLoaded event, running the anonymous function when the DOM is ready. The second line contains a simple jQuery statement: The first part is a CSS selector that selects a node or group of nodes for the action to be applied to, and the second part is a method that states the action to be applied. In this case, a class of foo will be added to all h1 elements.
Using the selector at the beginning of the statement can sometimes confuse people, as we construct sentences in English in the opposite way; it’s like saying “apple I will eat.” If it makes it easier for you to remember, imagine this is how Yoda would say it.
Using jQuery doesn’t limit you to DOM traversal or manipulation; it does plenty more as well. For example, you can use the on() method to attach events to elements—on() is like addEventListener with a few extra advantages, one of which is you can specify multiple event listeners to be added to a single element. In this example, an anonymous function runs whenever any h1 element is clicked or touched:
$('h1').on('click touch',function () { … });
Another fantastic feature of jQuery is its ability to chain methods in sequence, mixing selectors and actions to create long statements. The following code is a little more complex than I’ve used so far, so see if you can work out what it does before I explain it:
$('.foo').on('click', function (ev) {
$(ev.currentTarget).find('.bar').css('background-color','#f00');
});
Here’s the sequence: first, add a click event listener to all elements with the class of foo; next, run an anonymous function when that event is fired, and assign the event object to the variable named ev; in that function, find all elements with a class of bar that are children of the element that the event was fired on and change their background color to #f00.
The range of different methods that jQuery gives you access to is far greater than I could possibly list here, so I suggest you take a look at the documentation, which is absolutely exemplary—especially for an open source project.
jQuery has a companion called jQuery Mobile, which might at first sound like a mobile-optimized version of the library, but it’s not that simple; jQuery Mobile is actually an extension to jQuery that provides cross-platform widgets and styles, as well as new events and methods that take advantage of the new capabilities provided by mobile devices. It requires the jQuery library to run, meaning extra weight is added to your pages.
If you need a lightweight mobile-optimized library, you may want to consider an alternative such as Zepto.js, which features a jQuery-compatible API but is only 25 percent of its size. jQTouch is a library that provides many of the same features as jQuery Mobile but weighs in much lighter and is compatible with both jQuery and Zepto, although its browser support may not be as broad as that of jQuery Mobile. I advise you to evaluate each fully to find which one is best suited to your purposes.
I’ve already covered (back in Chapter 3) using media queries in CSS and JavaScript for loading resources depending on device dimensions, but what about all the other variable capabilities and functionality you could be testing against? Maybe you want to load resources depending on whether a browser has support for the console or a certain API (you’ll read more about those in Chapter 6). You could write custom functions that test for each critical dependency in turn, but using a conditional loader like YepNope.js might be a better option.
The idea of YepNope is incredibly simple: You give it a condition to test and then specify a resource to be loaded depending on the result. As a simple example, let’s test to see whether the browser has a console and load a virtual one if it doesn’t:
yepnope({
test: window.console,
nope: 'foo.js'
});
You can see what’s going on here pretty easily. The yepnope function is called. It has two properties: test, which is the condition to return either true or false; and nope, which is a resource to load if the value of test is false. So if window.console is supported, do nothing; if not, load foo.js.
A few further properties are available, such as yep, which specifies a resource to run if the value of test is true; both, which loads a resource regardless of the value of test; and callback, which runs a function when the test is complete. Let’s make the previous code example a bit more complex by adding a few of those in:
yepnope({
test: window.console,
yep: 'bar.js',
nope: 'foo.js',
both: 'foobar.css',
callback: function () { … }
});
Here I’m running the same test as before but now loading bar.js if test is true, foo.js if it’s false, and foobar.css regardless of the result. When the test has finished, the anonymous function runs.
Any test that returns a result of true or false can be run in test, but where YepNope.js really comes into its own is when it’s combined with Modernizr—the next library I discuss.
Browser support for experimental features, whether HTML, CSS, or JavaScript, can be quite variable, and providing safe fallbacks if a feature isn’t present in a user’s browser is not always easy. Modernizr, which runs a series of tests for features you define and then returns a result of true or false, addresses this problem.
Modernizr can be used in two principal ways: the first is through CSS. Say, for example, you want to check whether Flexbox properties are available in the user’s browser. First, you build a custom version of Modernizr with the build tool, being sure to click the flexbox option and include a link to the generated file in the head of your document. When the document has finished loading, a class of either flexbox or no-flexbox (depending on whether it’s available) is added to the html element.
That class could then be used to style the page depending on the level of Flexbox support; for example, you might have something like this, which makes an element display as a block by default but as a flex container for supporting browsers:
.foo { display: block; }
.flexbox .foo { display: flex; }
The second use of Modernizr is for conditional JavaScript. Each test you run creates a property for the Modernizr object, which has a true or false value for use with conditional functions; in this example, the code inside the curly brackets executes if Flexbox is supported:
if(Modernizr.flexbox) { … }
If you want to extend it to load external resources, you can use the Modernizr.load() method, which may look somewhat familiar if you’ve been paying attention so far:
Modernizr.load({
test: Modernizr.flexbox,
nope: 'foo.js'
});
Yes, it uses YepNope.js as a basis. All the properties of YepNope can be used in Modernizr. You can use Modernizr.load() alone, or, if you’re using YepNope already, use the Modernizr object as the test:
yepnope({
test: Modernizr.flexbox,
nope: 'foo.js'
});
Both work the same way. Your preference depends on your configuration, but whichever you opt for, the flexibility that Modernizr gives you is incredibly useful for building enhanced applications with graceful fallback.
The Modernizr concept of conditional style rules is so useful that it’s been adopted into CSS itself, using the @supports at-rule. @supports works similarly to media queries, but rather than testing for media features, it tests for CSS property-value pairs. For example, to test whether Flexbox is supported in a browser, use this rule:
@supports (display: flex) { … }
The declarations inside the curly brackets are applied to any browser that supports the flex value for the display property. You can read more about @supports and its associated API in Feature Queries.
If you’re building without a server backend or just want to get some static templates built quickly, you may want to consider a client-side template system. Preeminent among these is Mustache, a logic-less syntax that has proved its popularity by being ported to just about every major web programming language including, most appropriately for our purposes, JavaScript.
A logic-less syntax is one that doesn’t use any logical statements—no if, else, or or—instead using a system of tags that can be replaced by values. Here’s a basic example, substituting a single tag for a value:
var view = {
name: 'Bonobo'
}
var output = Mustache.render('The {{name}} is funny.', view);
You can see that I’ve created an object called view, with a single property name, which has the value ‘Bonobo’. In the output variable, I use the Mustache.render() method to create the tag replacement. This method has two arguments. In this example, the first is a string of text that contains the name property in double curly brackets (or “mustaches”)—this is the syntax for a tag. The variable inside it, known as the key, will be replaced by the property value with the same name from the object that is the second argument of the method—in this case, view. The final output will be the text 'The Bonobo is funny.', which you can see in Example 1 in the file mustache.html.
Using Mustache you can easily create sections of content that repeat—known, cleverly, as sections. Sections are useful for, for example, cutting the repetition needed for creating lists or tables. The first step is to set up the property-value pairs in the view object:
var view = {
'apes' : [
{'name':'Bonobo'},
{'name':'Chimpanzee'},
{'name':'Gorilla'},
{'name':'Orangutan'}
]
}
The syntax of a section is like a tag, but it has an opening and closing tag marked with # and /, respectively. In the following code, I output the section called apes with the text or HTML to be repeated:
var templApe = '{{#apes}}The {{name}} is funny.{{/apes}}';
Here I’ve created a new variable called templApe, which contains the repeating section. I could have added this directly inside Mustache.render(), but keeping my template rules separate in this way is more manageable. Anyway, I have my content and my template, so now I render it, outputting a list of four statements saying that each of the great apes is funny:
var output = Mustache.render(templApe,view);
You can see the result of this in Example 2 of mustache.html.
Sharing resources between pages makes templates more useful. The best way to share resources is to call an external file. Doing this is quite simple in Mustache; you just load the results of a JSON file into the view variable:
var request = new XMLHttpRequest();
request.open('GET', 'apes.json', true);
request.onreadystatechange = function () {
if (request.readyState != 4) { return; }
var view = JSON.parse(request.responseText);
1 var templApe = '{{#apes}}The {{name}} is funny.{{/apes}}';
2 var output = Mustache.render(templApe,view);
};
request.send();
1 and 2 are essentially the same as the previous example; the only difference is that the source of view is now data that has been parsed from the file apes.json, which contains the same information as the previous example but is held externally. You can see the output in Example 3 of mustache.html.
This example may look complicated because of the script required for getting the external data with an XMLHttpRequest; if you prefer to use jQuery, you could get the same result in fewer lines of code:
$.getJSON('json/apes.json', function (view) {
var templApe = '{{#apes}}The {{name}} is funny.{{/apes}}';
var output = Mustache.render(templApe,view);
});
This function is the same, but jQuery has abstracted away the XHR and JSON to make it all much simpler and to work cross-browser, which is what jQuery does best.
If you don’t like the idea of keeping templates in script, separate from your main content, you can use templates in the markup instead. Use inline script tags, with a type of text/template, with the template markup inside. For example, you could do this:
<div id="ape_area">
<script id="apeTpl" type="text/template">
<ul id="apes">
{{#apes}}<li>The {{name}} is funny.</li>{{/apes}}
</ul>
</script>
</div>
The script is similar to the previous example, except now you use a reference to the ID of the script tag, #apeTpl, to declare the template and overwrite the inline script to remove it from the markup at the time of rendering:
$.getJSON('json/data.json', function (view) {
var templApe = document.getElementById('apeTpl').innerHTML;
var output = Mustache.render(templApe,view);
document.getElementById('ape_area').innerHTML = output;
});
Example 4 of mustache.html shows this in action. Whether you use the inline templating system comes down to your personal preference, but Mustache offers the advantage of making these alternative approaches available.