This is an old revision of the document!
Table of Contents
~~SLIDESHOW~~
JavaScript Libraries and jQuery
Contact Hour 14: To be discussed on Wednesday 27th February, 2013.
Presenter: Dr Chris P. Jobling.
As a way of getting around browser quirks, the web developer community, including some major players like Google and Yahoo, have developed and released JavaScript libraries. In this session we will explore the idea of a JavaScript library, mention some of the general purpose and specialized open-source libraries that exist, and introduce jQuery, one of the most widely used JavaScript libraries.
JavaScript Libraries
- JavaScript is a small language
- It doesn't come with large numbers of libraries and objects
- Differences between browsers make JavaScript DOM programming challenging
- JavaScipt can be used to solve these problems itself
- Solutions to common problems have been shared as open source JavaScript libraries
JavaScript is a small language that can be covered in about two weeks worth of lectures if you already know a c-like programming language. Unlike technologies like .NET, Java and Cocoa, it doesn't come with large numbers of libraries and objects that we can use to develop we applications. Unfortunately, even for the limited requirement of manipulating the DOM, differences between browsers make JavaScript more challenging than it should be. Fortunately, many of the problems can be solved using JavaScipt itself, and even better, solutions have been made into open source libraries that have been shared on the Internet.
This material, including some of the examples, is based in part on Chapter 11 of Simon Allardice, JavaScript Essential Training (2011), lynda.com, 22 July 2011. URL: http://www.lynda.com/JavaScript-tutorials/Essential-Training-2011/81266-2.html accessed 18 February 2012 and Joe Marini, Essential jQuery Training, lynda.com, 9 January 2009. URL: http://www.lynda.com/jQuery-tutorials/essential-training/48370-2.html accessed 18 February 2012. For a free alternative see Buck Rogers, jQuery Tutorial (200 videos), thenewboston.com, URL: http://thenewboston.org/list.php?cat=32, last accessed 18 February 2012.
Other examples are taken from public sources on the Internet which are cited in the notes.
For a previous version of these notes see Old JavaScript Libraries notes.
Contents of this Session
Learning Outcomes
At the end of this lecture you should be able to answer these questions:
- What features are typically provided by a general purpose JavaScript library?
- What features are typically provided by a specialized JavaScript library?
- How is a JavaScript library typically loaded?
- Why is is recommended that most scripts and libraries are loaded at the end of an HTML document?
Learning Outcomes (2)
At the end of this lecture you should be able to answer these questions:
- List the main sections of the jQuery API
- What is the difference between selection and filtering in jQuery?
- Would it be a good idea to use jQuery's CSS selection as a replacement for style sheets?
- What are the two ways to assign an event handler to an element with jQuery?
- What attributes and methods does the jQuery event object have?
Learning Outcomes (3)
At the end of this lecture you should be able to answer these questions:
- What does the jQuery function return?
- How does the object returned by the jQuery function allow chaining of functions?
- Give an example of jQuery's animation method.
- What widgets does the standard JQuery UI library contain?
- Why is jQuery code usually embedded in an anonymous function passed as a parameter to the
jQuery(“document”).ready()
function? - What advantage does loading a JavaScript library from a CDN have?
General Purpose JavaScript Libraries
Typical Features
- Navigating the DOM
- retrieving elements
- modifying element attributes or contents
- putting modified elements back into DOM
- Cross-browser event handling
- Cross-browser animation
- Support for AJAX
Specialized JavaScript Libraries
For specialized features:
- Lightbox2 – image display
- Script.aculo.us – visual effects, animation and UI controls
- moofx – visual effects
- CurveyCorners – rounded corners on browsers that don't support CSS3
- webforms2 – cross-browser support for full WebForms 2.0 spec (see HTML Forms the Next Generation)
- TinyMCE – adds Word toolbar-like features and WYSIWYG editing to text areas on web forms
Some JavaScript libraries are more specialized. Rather than be general purpose, things like Lightbox are simply JavaScript libraries for popping up images on your web site. You've probably seen these ones before. They might be for slideshows. They might be for implementing things like drag-and-drop and working with accordions. They could be as simple as a library that just helps you add curved corners to your divs. And some, might be used as polyfills that make standards that are not yet implemented in browsers – such as the full web forms 2 standard – or back-port features such as those introduced in HTML5 to older browsers.
Most of these libraries are open source and they are free. There is no licensing. You simply grab the code and use it, do whatever you want with it. So we encourage you to explore what's available, and new ones are appearing all the time.
MVC JavaScript Libraries
- JavaScript frameworks for rich client-side interaction
- Designed to separate code for the presentation of data (Model) in DOM (View) from the model (Application) data itself.
- Controllers for coordination of data flow, state management, routing, browser history control, etc.
- For now see collection in TodoMVC
To be discussed in a later session.
Using Libraries
- Simply download
- Include in document using
<script>
tag
The lastest jQuery is always on the Downloading jQuery page. Note, many libraries come in two forms, the development version that includes the code and comments, and a minified version that has been manipulated to make it as small as possible. You would normally download both and use the development version when you are developing code (you can debug scripts easier) and the production code, which saves bandwidth, but is ureadable, for deployed web sites.
Using Libraries
<!DOCTYPE html> <html lang="en"> <head><meta charset="utf-8" /> <title> Loading JavaScript libraries</title> </head> <body> <p>According to current best practice, you should load your scripts last.</p> <p>Order is important!</p> <script src="some_library.js"></script> <script src="useful_functions.js"></script> <script src="app_scripts.js"></script> <script> // custom per page scripts here </script> </body> </html>
The idea of putting scripts last is that they will be loaded once the HTML has been read and the DOM constructed.
The order that scripts are loaded is important. You should generally load any library files before the scripts that build on those libraries and finally load any page-specific scripts last.
Each script is loaded, using a HTTP GET request, in the order listed. Unlike other assets such as images, no parallel requests are made. The next script is only loaded when the first script has been downloaded and executed. Thus the more scripts there are the longer they will take to load and the longer the delay before the user can start to use the application. Thus, although it is useful for development to have separate files for each library, you should avoid having many scripts in production. Put them together if you can and minify the result to reduce the size of the downloads. Some development tools and frameworks will do this automatically. For example, see the HTML5 Ant Build Script.
jQuery
- Possibly most widely used of the JavaScript libraries
- Available from jQuery.com
- Designed to simplify and unify across browsers
- CSS Selectors for finding elements
- DOM manipulation
- Event handling
- Animation
JavaScript Selection
Without jQuery (View on jsFiddle):
// Return element var element = document.getElementById("myDiv"); element.className="highlight"; // destructive! // Return an array of elements var elements = document.getElementsByTagName("p"); for (e = 0; e < elements.length; e++) { elements[e].className="highlight"; }
No other selections are possible. Once a single element or set of elements is selected, you have to walk through the DOM to find an manipulate the remaining elements.
document.getElementById
returns element withid=“myDiv”
ornull
if there is no such object.document.getElementsByTagName(“p”)
returns an array of the paragraphs in a document or the empty array- setting className is descructive, it removes whatever was there before.
- For an array, we have to move through each element to apply the change
The jQuery Function
- jQuery library adds a single function
jQuery(selector)
which accepts a string containing a CSS selector which is then used to match a set of elements. - Elements returned can be further filtered
- Elements returned can all be manipulated by chaining functions
Fiddle with jQuery
Play with this example on jsFiddle
jQuery Features
Cross-browser support for:
Feature Group | Purpose | Feature Group | Purpose |
---|---|---|---|
Selectors | Using CSS selectors to matching a set of elements in a document | Attributes | Get and set DOM attributes of elements |
Traversing | Moving through the DOM | Manipulation | Changing the DOM |
CSS | Changing the styles of an element using CSS | Events | Cross browser event handling |
Effects | Animation effects | Ajax | Scriptable HTTP requests for partial page updates |
The best place to find out about these is by following the links to the jQuery API Documentation on the main Documentation Page.
jQuery Selection
With jQuery:
jQuery("#myDiv").addClass("highlight"); jQuery("p").addClass("highlight");
Here addClass
is not destructive…it adds the class. Same command used for single element and array of element. jQuery takes care of the selection of elements and the iteration through a collection.
There is also a removeClass(class_name)
and a toggleClass(class_name)
function. The first removes the named class (and only the named class); the second toggles the class – adds it if it doesn't exist, removes it if it does.
More Selectors
- Selection by tag, id, class, attribute, just like in CSS
jQuery("#someId"); // by id jQuery(".someClass"); // by class jQuery("p"); jQuery("a"); jQuery("li");// by tag jquery("p.description"); // combination of tag and class jQuery("p + p"); jQuery("div > p"); // more complex relationships jQuery("a[href~='swansea.ac.uk']"); // by attribute value
See jQuery Selectors for more documentation and examples
If your CSS is a bit rusty:
p.description
matches<p class=“description”>…</p>
p + p
matches a paragraph that is a sibling of a paragraph, that is for
<p>First paragraph</p> <p>Second paragraph</p> <p>Third paragraph</p>
jQuery(“p + p”)
would return
["<p>Second paragraph</p>","<p>Third paragraph</p>"];
div > p
returns all the<p>
elements that are direct descendents (children) of a<div>
(the parent).jQuery(“a[href~='swansea.ac.uk']”)
returns all<a>
(anchor or link) elements whosehref
attribute contains the stringswan.ac.uk
.
Filters
- Filtering by equivalent of CSS pseudo classes
- See this example on jsFiddle
jQuery("p:first"); // first match jQuery("p:last"); // last match jQuery("p:even"); // even numbered array index (zero base) jQuery("p:contains('interesting')"); jQuery("p:hidden");
These can be combined with any of the other selectors, for example
jQuery("p.description:first"); jQuery("p.description:contains('interesting')");
Attributes
Most commonly used:
jQuery('a').attr('href'); // getter jQuery('a').attr('href','http://www.swan.ac.uk'); // setter // Setting multiple attributes jQuery('a').attr({href: "http://www.swan.ac.uk", title: "Home page"}); jQuery('p').html(); jQuery('p').html("<span>Some content</span>"); jQuery('#someInput').val(); jQuery('#someInput').val('new value');
Illustrated in this jsFiddle
See jQuery Attributes for more examples and details.
All functions can be used in a getter (no params) or setter mode. Some setters can take a variety of arguments, such as (name, value)
or objects {par1: val1, par2, val2}
used to set multiple values at once.
Traversing the DOM
Functions that help you move around the selection set:
jQuery('p').add('<span>A Span</span>'); var children = jQuery('p').children(); jQuery('li').each(function(index) { alert(index + ': ' + $(this).text()); }); jQuery('p').previous(); jQuery('p').next();
See jsFiddle for a demonstration of these functions.
See jQuery Traversing for more examples and details.
DOM Manipulation
Functions that help you change the currently selected elements.
An example1)
jQuery('p').hide().css({'border', '3px solid red'}).fadeIn(2000);
To play with this example see this jsFiddle
See jQuery Manipulation for more DOM manipulation functions and examples.
The code example includes an example of CSS manipulation and animation. It will select all paragraphs in the document, initially hide them, apply the equivalent css style
p { border: 3px solid red; }
then make each paragraph fade in to the document over a period of 2000 ms (2 seconds).
The function jQuery
is aliased to $
so you will often see the jQuery function written $('<p>')
as opposed to jQuery('<p>')
. So the example would be simplified to
$('<p>').hide().css({'border', '3px solid red'}).fadeIn(2000);
CSS
Functions to add and remove classes from elements, change the CSS directly (equivalent to applying a local style setting to the selected elements), and some special functions for obtaining positional information from elements.
jQuery('p').addClass("highlight"); jQuery('p').css("border","3px solid red"); var position = jQuery("#specialDiv").position(); console.log("left = " + position.left + "; top = " + position.top);
See this example in jsFiddle
See jQuery CSS for more ideas.
Events
- In browsers events are either handled the DOM level 2 way (see JavaScript and HTML Part 2) or the “Internet Explorer Way”
- jQuery Event APIs provide a cross-browser way to register event handlers as well as
- A cross-browser valid definition of the event object
- They are used to register behaviors that take effect when the user interacts with the browser, and to further manipulate those registered behaviors.
To play with events, try this jsFiddle
For a full list of events and event properties see jQuery Events
Binding Events to Elements
Use the on
function:
jQuery('[type="radio"]').on("click", function() { alert("Button " + $(this).val() + " clicked"}); });
Simplified Event Registration Functions
jQuery('#target').click(function() { alert("Target clicked"); }); jQuery("#other").click(function() { $("#target").click(); });
Functions exist for most of the common events, mouse events and key events. The names are the same as for the HTML attributes: e.g. onblur
has jQuery binding function blur
.
</code>
The jQuery Event Object
- All event functions can take an [optional] event object as an argument.
- This provides a browser-agnostic way of getting and setting useful event properties in a browser independent way
event.type // type of event event.target // original target of the event event.currentTarget // target of the event during bubbling event.pageX // mouse coordinates of event event.pageY event.preventDefault() // stop the default action (e.g. submit) event.stopPropagation() // stop bubbling
Animation Effects
Various ways to change the display
jQuery('p').hide(); jQuery('p').hide('slow'); jQuery('p').fadeIn(); jQuery('p').slideDown(4000); jQuery('p').animate({opacity: 0.25, left: '+=50', height: 'toggle'}, 5000, function() { alert('Animation complete') });
For more information and examples see jQuery Effects
AJAX
Will be discussed in the session on AJAX
The $ Shortcut
It has become a convention to alias the jQuery
function to the one-letter variable $
. Thus you will see
$('p').addClass('highlight');
rather than
jQuery('p').addClass('highlight');
but both are equivalent.
In fact there is a definition in the jQuery code:
window.jQuery = window.$ = jQuery;
Recall that and JavaScript variable or function that is added to the window
object is global to the web app.
Loading jQuery Scripts
$(document).ready(function() { // your code here });
Runs the code (e.g. to add classes, event handlers etc) when the DOM is fully loaded.
This is often shortened to this:
$(function() { // your code here });
Notes:
- the
$(“document”).ready()
function will only be called when the DOM is fully loaded and available for processing by JavaScript. - You can also have multiple calls to
$(document).ready()
and they will be executed in the order encountered. This allows you to modularize your code: for example to separate form validation from animation. - By declaring the code to be executed by jQuery as the body of an anonymous function you ensure that all the variables declared in the code block will be not visible to the rest of JavaScript. This prevents name clashes when using libraries and scripts from different sources.
Putting it All Together
The jQuery Events example from this document re-implemented as a stand-alone script.
The Markup:
<!DOCTYPE html> <!-- validator.html An example of input validation using the change and submit events --> <html class="no-js" lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Illustrate form input validation</title> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/vendor/modernizr-2.6.2-respond-1.1.0.min.js"></script> </head> <body> <div class="container"> <h1>Illustrating jQuery</h1> <section> <h2> jQuery Events </h2> <form id="myForm" action="/cgi-bin/echo_params.cgi"> <fieldset> <legend>Types of Plane</legend> <div class="control-group"> <label class="radio"> <input type="radio" name="planeButton" value="152" />Model 152</label> <label class="radio"> <input type="radio" name="planeButton" value="172" />Model 172 (Skyhawk)</label> <label class="radio"> <input type="radio" name="planeButton" value="182" />Model 182 (Skylane)</label> <label class="radio"> <input type="radio" name="planeButton" value="210" />Model 210 (Centurian)</label> </div> </fieldset> </form> </section> <section> <h2>Simplified Event Regsitration</h2> <ol> <li>Add an event listener to button labelled "Target" that shows an alert when it is clicked</li> <li>Add an event listener to button labelled "Other" that clicks the "Target" button.</li> <div class="control-group"> <button id="target" class="btn">Target</button> <button id="other" class="btn">Other</button> </div> </ol> </section> <section> <h2>The jQuery event object</h2> <div id="outer"> <p>The event will bubble out from the button in the inner div. It should stop bubbling before it reaches the outer div and the form should not submit.</p> <div id="inner"> <form name="myForm" action="http://www.google.co.uk/#hl=en" class="form-search"> <div class="input-append"> <input type="text" placeholder="type something" name="q" class="span2 search-query" /> <button class="btn" type="submit">Search</button> </div> </form> </div> <!-- inner --> </div> <!-- outer --> </section> </div> <!-- /container --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/plugins.js"></script> <!-- Any external JS loaded here --> <script src="jquery_events.js"></script> </body> </html>
The JavaScript:
$(document).ready(function() { // The event handler for a radio button collection var planeChoice = function (plane) { // Produce an alert message about the chosen airplane switch (plane) { case "152": alert("A small two-place airplane for flight training"); break; case "172": alert("The smaller of two four-place airplanes"); break; case "182": alert("The larger of two four-place airplanes"); break; case "210": alert("A six-place high-performance airplane"); break; default: alert("Error in JavaScript function planeChoice"); break; } }; var describeEvent = function(event, source) { console.log("Handler caught " + event.type + " event from " + source); console.log("Original target") console.log(event.target); console.log("Current target"); console.log(event.currentTarget); console.log("Mouse coordinates: [" + event.pageX + ", " + event.pageY + "]"); }; // Register event handlers for radio buttons $('[name="planeButton"]').on("click", function(event) { console.log(describeEvent(event,"planeButton")); plane = $(this).val(); console.log("Button " + plane + " clicked"); planeChoice(plane); }); // Simplified event registration $('#target').click(function(event) { console.log(describeEvent(event,"Target Button")); alert("Target button clicked"); }); $('#other').click(function(event) { console.log(describeEvent(event,"Other Button")); alert("Other button clicked ... now clicking 'target'"); $('#target').click(); }); // The jQuery event object - allows us to explore bubbling jQuery('button[type="submit"]').on("click", function(event) { describeEvent(event, "'Search' button"); // stop form being submitted event.preventDefault(); }); jQuery('#inner').on("click", function(event) { describeEvent(event, "'#inner' div"); // stop bubbling here event.stopPropagation(); }); jQuery('#outer').on("click", function(event) { // should never fire! describeEvent(event, "'#outer' div"); }); });
The Form Validator Again
- Re-implemented using jQuery event handling validator.html
The HTML is unchanged!
// Form validator re-implemented in jQuery $(document).ready(function() { // The event handler function for the name text box var chkName = function(event) { var myName = event.target; // Test the format of the input name // Allow the spaces after the commas to be optional // Allow the period after the initial to be optional var pos = myName.value.search(/^[A-Z][a-z]+, ?[A-Z][a-z]+, ?[A-Z]\.?$/); if (pos != 0) { alert("The name you entered (" + myName.value + ") is not in the correct form. \n" + "The correct form is: " + "Last name, First name, Middle initial \n" + "Please go back and fix your name"); myName.focus(); myName.select(); return false; } else return true; }; // The event handler function for the phone number text box var chkPhone = function(event) { var myPhone = event.target; // Test the format of the input phone number var pos = myPhone.value.search(/^\d{3}-\d{3}-\d{4}$/); if (pos != 0) { alert("The phone number you entered (" + myPhone.value + ") is not in the correct form. \n" + "The correct form is: ddd-ddd-dddd \n" + "Please go back and fix your phone number"); myPhone.focus(); myPhone.select(); return false; } else return true; }; var validate_form = function(event) { if (! chkName(event) || ! chkPhone(event)) { event.preventDefault(); } }; // Register event handlers $("#custName").change(chkName); $("#phone") .change(chkPhone); $("#submit") .click(validate_form); });
jQuery UI Components
- A large library of interactions, widgets, utilities and effects.
- Too many to describe here.
- See jQuery UI
Using CDN
- Instead of hosting your own copy of jQuery or jQuery-UI, use a Content Distribution Network
- E.g. using the Google API Code CDN
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> <script src="script.js">
</code>
This ensures that the jQuery library is loaded from a host that is closer to the end-user than you are and is likely to be cached, by your browser or an ISP web-cache.
If you have an encrypted site, you need to download your resources from an encrypted source to avoid complaints from your browser. If you use
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> <script src="script.js">
</code>
The protocol will match whatever the enclosing page was. So if you access the page from http://...
it will get http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
if your page was encypted it will have used https://...
and the library will be loaded using https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
Summary of this Session
References
- Simon Allardice, JavaScript Essential Training (2011), Chapter 11, lynda.com, 22 July 2011. URL: http://www.lynda.com/JavaScript-tutorials/Essential-Training-2011/81266-2.html accessed 18 February 2012
- Joe Marini, Essential jQuery Training, lynda.com, 9 January 2009. URL: http://www.lynda.com/jQuery-tutorials/essential-training/48370-2.html accessed 18 February 2012.
- Addy Osmani and Sinder Sorhus, TodoMVC. URL: http://addyosmani.github.com/todomvc/.
Further Resources
- For a free alternative to the lynda.com tutorials see Buck Rogers, jQuery Tutorial (200 videos), thenewboston.com, URL: http://thenewboston.org/list.php?cat=32, last accessed 18 February 2012.
Learning Outcomes
At the end of this lecture you should be able to answer these questions:
- What features are typically provided by a general purpose JavaScript library?
- What features are typically provided by a specialized JavaScript library?
- How is a JavaScript library typically loaded?
- Why is is recommended that most scripts and libraries are loaded at the end of an HTML document?
Learning Outcomes (2)
At the end of this lecture you should be able to answer these questions:
- List the main sections of the jQuery API
- What is the difference between selection and filtering in jQuery?
- Would it be a good idea to use jQuery's CSS selection as a replacement for style sheets?
- What are the two ways to assign an event handler to an element with jQuery?
- What attributes and methods does the jQuery event object have?
Learning Outcomes (3)
At the end of this lecture you should be able to answer these questions:
- What does the jQuery function return?
- How does the object returned by the jQuery function allow chaining of functions?
- Give an example of jQuery's animation method.
- What widgets does the standard JQuery UI library contain?
- Why is jQuery code usually embedded in an anonymous function passed as a parameter to the
jQuery(“document”).ready()
function? - What advantage does loading a JavaScript library from a CDN have?
Homework Exercises
- Convert all of the Dom 2 Exercises to jQuery