Chapter 2
In This Chapter
Downloading and including the jQuery library
Making an AJAX request with jQuery
Using component selectors
Adding events to components
Creating a simple content management system with jQuery
JavaScript has amazing capabilities. It's useful on its own, and when you add AJAX, it becomes incredibly powerful. However, JavaScript can be tedious. You have a lot to remember, and it can be a real pain to handle multiplatform issues. Some tasks (like AJAX) are a bit complex and require a lot of steps. Regardless of the task, you always have browser-compatibility issues to deal with.
For these reasons, web programmers began to compile commonly used functions into reusable libraries. These libraries became more powerful over time, and some of them have now become fundamental to web development.
As these libraries became more powerful, they not only added AJAX capabilities, but many of them also added features to JavaScript/DOM programming that were once available only in traditional programming languages. Many of these libraries allow a new visual aesthetic as well as enhanced technical capabilities.
A number of very powerful JavaScript/AJAX libraries are available. All make basic JavaScript easier, and each has its own learning curve. No library writes code for you, but a good library can handle some of the drudgery and let you work instead on the creative aspects of your program. JavaScript libraries can let you work at a higher level than plain JavaScript, writing more elaborate pages in less time.
Several important JavaScript/AJAX libraries are available. Here are a few of the most prominent:
This book focuses on the jQuery library. Although many outstanding AJAX/JavaScript libraries are available, jQuery has quickly become one of the most prominent. Here are some reasons for the popularity of jQuery:
The jQuery library is easy to install and use. Follow these steps:
As of this writing, the most current version is 1.10.2. There is a 2.X series, but these versions do not support older browsers, so will not be adopted until the older browsers (particularly IE 6 and less) are no longer used at all.
You may be able to choose from a number of versions of the file. I recommend the minimized version for actual use. To make this file as small as possible, every unnecessary character (including spaces and carriage returns) was removed. This file is very compact but difficult to read. Download the nonminimized version if you want to actually read the code, but it's generally better to include the minimized version in your programs.
jQuery-1.10.2.min.js is the current file.
To incorporate the library in your pages, simply link to it as an external JavaScript file:
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
This has a couple of interesting advantages:
Here's how you do it:
<script type = "text/javascript"
src="http://www.google.com/jsapi"></script>
<script type = "text/javacript">
// Load jQuery
google.load("jquery", "1");
//your code here
</script>
Essentially, loading jQuery from Google is a two-step process:
Use the first <script> tag to refer to the Google AJAX API server. This gives you access to the google.load() function.
Note that you don't need to install any files locally to use the Google approach.
As an introduction to jQuery, build an application that you can already create in JavaScript/DOM. This introduces you to some powerful features of jQuery. Figure 2-1 illustrates the change.html page at work, but the interesting stuff (as usual) is under the hood.
At first, the jQuery app doesn't look much different than any other HTML/JavaScript code you've already written, but the JavaScript code is a bit different:
<!DOCTYPE html>
<html lang = "en-US">
<head>
<title>change.html</title>
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
function changeMe(){
$("#output").html("I changed");
}
</script>
</head>
<body onload = "changeMe()">
<h1>Basic jQuery demo</h1>
<div id = "output">
Did this change?
</div>
</body>
</html>
The basic features of changeme.html are utterly unsurprising:
$("#output").html("I changed");
The secret behind jQuery's power is the underlying data model. jQuery has a unique way of looking at the DOM that's more powerful than the standard object model. Understanding the way this works is the key to powerful programming with jQuery.
You have many ways to create a jQuery object, but the simplest is through the special $() function. You can place an identifier (very similar to CSS identifiers) inside the function to build a jQuery object based on an element. For example,
var jQoutput = $("#output");
creates a variable called jQoutput, which contains a jQuery object-based on the output element. It's similar to the following:
var DOMoutput = document.getElementById("output");
The jQuery approach is a little cleaner, and it doesn't get a reference to a DOM object (as the getElementById technique does), but it makes a new jQuery object that is based on the DOM element. Don't worry if this is a little hard to understand. It gets easier as you get used to it.
Because jQoutput is a jQuery object, it has some powerful methods. For example, you can change the content of the object with the html() method. The following two lines are equivalent:
jQoutput.html("I've changed"); //jQuery version
DOMoutput.innerHTML = "I've changed"; //ordinary JS / DOM
jQuery doesn't require you to create variables for each object, so the code in the changeMe() function can look like this:
//build a variable and then modify it
var jQoutput = $("#output");
jQoutput.html("I've changed");
Or you can shorten it like this:
$("#output").html("I've changed");
This last version is how the program is actually written. It's very common to refer to an object with the $() mechanism and immediately perform a method on that object as I've done here.
Many pages require an initialization function. This is a function that's run early to set up the rest of the page. The body onload mechanism is frequently used in DOM/JavaScript to make pages load as soon as the document has begun loading. This technique is described in Book IV, Chapter 7. While body onload does this job well, a couple of problems exist with the traditional technique:
jQuery has a great alternative to body onload that overcomes these shortcomings. Take a look at the code for ready.html to see how it works:
<!DOCTYPE html>
<html lang = "en-US">
<head>
<title>ready.html</title>
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(document).ready(changeMe);
function changeMe(){
$("#output").html("I changed");
}
</script>
</head>
<body>
<h1>Using the document.ready mechanism</h1>
<div id = "output">
Did this change?
</div>
</body>
</html>
This code is much like change.html, but it uses the jQuery technique for running initialization code:
You sometimes see a couple of shortcuts because it's so common to run initialization code. You can shorten
$(document).ready(changeMe);
to the following code:
$(changeMe);
If this code is not defined inside a function and changeMe is a function defined on the page, jQuery automatically runs the function directly just like the document.ready approach.
You can also create an anonymous function directly:
$(document).ready(function(){
$("#output").html("I changed");
});
$(init);
I think this technique is simple and easy to understand but you may encounter the other variations as you examine code on the web.
The jQuery object is interesting because it is easy to create from a variety of DOM elements, and because it adds wonderful, new features to these elements.
If you can dynamically change the CSS of an element, you can do quite a lot to it. jQuery makes this process quite easy. After you have a jQuery object, you can use the css() method to add or change any CSS attributes of the object. Take a look at styleElements.html, shown in Figure 2-2, as an example.
The code displays a terseness common to jQuery code:
<!DOCTYPE html>
<title>styleElements.html</title>
<meta charset="UTF-8">
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(init);
function init(){
$("h1").css("backgroundColor", "yellow");
$("#myParagraph").css({"backgroundColor":"black",
"color":"white"});
$(".bordered").css("border", "1px solid black");
}
</script>
</head>
<body>
<h1>I'm a level one heading</h1>
<p id = "myParagraph">
I'm a paragraph with the id "myParagraph."
</p>
<h2 class = "bordered">
I have a border.
</h2>
<p class = "bordered">
I have a border too.
</p>
</body>
</html>
You find a few interesting things in this program. First, take a look at the HTML:
The init() function is identified as the function to be run when the document is ready. In this function, I use the powerful CSS method to change each element's CSS dynamically. I come back to the CSS in a moment, but first notice how the various elements are targeted.
jQuery gives you several alternatives for creating jQuery objects from the DOM elements. In general, you use the same rules to select objects in jQuery as you do in CSS:
These selection methods (all borrowed from familiar CSS notation) add incredible flexibility to your code. You can now easily select elements in your JavaScript code according to the same rules you use to identify elements in CSS.
For example, to make the background color of all H1 objects yellow, I use the following code:
$("h1").css("backgroundColor", "yellow");
If you apply a style rule to a collection of objects (like all H1 objects or all objects with the bordered class), the same rule is instantly applied to all the objects.
A more powerful variation of the style rule exists that allows you to apply several CSS styles at once. It takes a single object in JSON notation as its argument:
$("#myParagraph").css({"backgroundColor":"black",
"color":"white"});
This example uses a JSON object defined as a series of rule/value pairs. If you need a refresher on how JSON objects work, look at Book IV, Chapter 4.
The jQuery library adds another extremely powerful capability to JavaScript. It allows you to easily attach events to any jQuery object. As an example, take a look at hover.html, as shown in Figure 2-3.
When you move your cursor over any list item, a border appears around the item. This isn't a difficult effect to achieve in ordinary CSS but it's even easier in jQuery.
Look at the code to see how it works:
<!DOCTYPE html>
<html lang="en">
<head>
<title>hover.html</title>
<meta charset="UTF-8">
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(init);
function init(){
$("li").hover(border, noBorder);
} // end init
function border(){
$(this).css("border", "1px solid black");
}
function noBorder(){
$(this).css("border", "0px none black");
}
</script>
</head>
<body>
<h1>Hover Demo</h1>
<ul>
<li>alpha</li>
<li>beta</li>
<li>gamma</li>
<li>delta</li>
</ul>
</body>
</html>
The HTML couldn't be simpler. It's simply an unordered list. The JavaScript isn't much more complex. It consists of three one-line functions:
In this example, I used three different functions. Many jQuery programmers prefer to use anonymous functions (sometimes called lambda functions) to enclose the entire functionality in one long line:
$("li").hover(
function(){
$(this).css("border", "1px solid black");
},
function(){
$(this).css("border", "0px none black");
}
);
Note that this is still technically a single line of code. Instead of referencing two functions that have already been created, I build the functions immediately where they are needed. Each function definition is a parameter to the hover() method.
Although I'm perfectly comfortable with anonymous functions, I often find the named-function approach easier to read, so I tend to use complete named functions more often. All those braces inside parentheses make me dizzy.
jQuery supports another wonderful feature. You can define a CSS style and then add or remove that style from an element dynamically. Figure 2-4 shows a page that can dynamically modify the border of any list item.
The code shows how easy this kind of feature is to add:
<!DOCTYPE html>
<html lang="en">
<head>
<title>class.html</title>
<meta charset="UTF-8">
<style type = "text/css">
.bordered {
border: 1px solid black;
}
</style>
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(init);
function init(){
$("li").click(toggleBorder);
} // end init
function toggleBorder(){
$(this).toggleClass("bordered");
}
</script>
</head>
<body>
<h1>Class Demo</h1>
<ul>
<li>alpha</li>
<li>beta</li>
<li>gamma</li>
<li>delta</li>
</ul>
</body>
</html>
Here's how to make this program:
All the interesting stuff happens in CSS and JavaScript, so the actual contents of the page aren't that critical.
I build a CSS class called bordered that simply draws a border around the element. Of course, you can make a much more sophisticated CSS class with all kinds of formatting if you prefer.
As you're beginning to see, most jQuery applications require some sort of initialization. I normally call the first function init().
The init() method simply sets up an event handler. Whenever a list item receives the click event (that is, it is clicked) the toggleBorder() function should be activated. The toggleBorder() function, well, toggles the border.
jQuery has several methods for manipulating the class of an element:
The primary purpose of an AJAX library like jQuery is to simplify AJAX requests. It's hard to believe how easy this can be with jQuery. Figure 2-5 shows ajax.html, a page with a basic AJAX query.
This program is very similar in function to the asynch.html program described in Chapter 1 of this minibook, but the code is much cleaner:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax.html</title>
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(document).ready(getAJAX);
function getAJAX(){
$("#output").load("hello.txt");
}
</script>
</head>
<body>
<div id = "output"></div>
</body>
</html>
The HTML is very clean (as you should be expecting from jQuery examples). It simply creates an empty div called output.
The JavaScript code isn't much more complex. A standard $(document).ready function calls the getAJAX() function as soon as the document is ready. The getAJAX() function simply creates a jQuery node based on the output div and loads the hello.txt file through a basic AJAX request.
The load() mechanism described here is suitable for a basic situation where you want to load a plain-text or HTML code snippet into your pages. You read about much more sophisticated AJAX techniques in Chapter 6 of this minibook.
AJAX and jQuery can be a very useful way to build efficient websites, even without server-side programming. Frequently a website is based on a series of smaller elements that can be swapped and reused. You can use AJAX to build a framework that allows easy reuse and modification of web content.
As an example, take a look at cmsAJAX, shown in Figure 2-6.
Although nothing is all that shocking about the page from the user's perspective, a look at the code can show some surprises:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>CMS Using AJAX</title>
<link rel = "stylesheet"
type = "text/css"
href = "cmsStd.css" />
<script type = "text/javascript"
src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
$(init);
function init(){
$("#heading").load("head.html");
$("#menu").load("menu.html");
$("#content1").load("story1.html");
$("#content2").load("story2.html");
$("#footer").load("footer.html");
};
</script>
</head>
<body>
<div id = "all">
<!-- This div centers a fixed-width layout -->
<div id = "heading">
</div><!-- end heading div -->
<div id = "menu">
</div> <!-- end menu div -->
<div class = "content"
id = "content1">
</div> <!-- end content div -->
<div class = "content"
id = "content2">
</div> <!-- end content div -->
<div id = "footer">
</div> <!-- end footer div -->
</div> <!-- end all div -->
</body>
</html>
Look over the code, and you can see these interesting features:
<h2>Book I - Creating the HTML Foundation</h3>
<ol>
<li>Sound HTML Foundations</li>
<li>It's All About Validation</li>
<li>Choosing your Tools</li>
<li>Managing Information with Lists and Tables</li>
<li>Making Connections with Links</li>
<li>Adding Images</li>
<li>Creating forms</li>
</ol>
This approach may seem like a lot of work, but it has some very interesting characteristics:
The advantage of the template-style approach is code reuse. Just like the use of an external style allows you to multiply a style sheet across hundreds of documents, designing a template without content allows you to store code snippets in smaller files and reuse them. All 100 pages point to the same menu file, so if you want to change the menu, you change one file and everything changes with it.
Here's how you use this sort of approach:
Build basic HTML and CSS to manage the overall look and feel for your entire site. Don't worry about content yet. Just build placeholders for all the components of your page. Be sure to give each element an ID and write the CSS to get things positioned as you want.
Make a link to the jQuery library, and make a default init() method. Put in code to handle populating those parts of the page that will always be consistent. (I use the template shown here exactly as it is.)
After you have a sense of how the template will work, make a copy for each page of your site.
The only part of the template that changes is the init() function. All your pages will be identical, except they have customized init() functions that load different content.
Use the init() function to load content into each div. Build more content as small files to create new pages.