This guide is a introduction to the jQuery library. Knowledge of javascript and the document object model (DOM) is required. It starts from ground up and tries to explain details where necessary. It covers a simple hello world example, selector and event basics, AJAX, FX and usage of plugins.
This guide contains no "click me" examples. The intention of providing only "copy me" code is to invite you to try it for yourself. Copy an example, see what it does, and modify it.
To start, we need a copy of the jQuery library. While the most recent version can be found here, this guide provides a basic package you can download.
Download this file and extract it. Open starterkit.html file with a browser and the custom.js with your favorite editor.
Now we have everything to start with the notorious "Hello world" example.
As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.
To do this, we register a ready event for the document.
$(document).ready(function() {
// do stuff when DOM is ready
});
Putting an alert into that function does not make much sense, as an alert does not require the DOM to be loaded. So lets try something a little more sophisticated: Show an alert when clicking the link.
$(document).ready(function() {
$("a").click(function() {
alert("Hello world!");
});
});
This should show the alert as soon as you click on the link.
Lets have a look at what we are doing: $("a") is a jQuery selector, in this
case, it selects all a elements. $ itself is an alias for the jQuery "class", therefore
$() constructs a new jQuery object. The click() function we call next is a
method of the jQuery object. It binds a click event to all selected elements (in this case, a single
anchor element) and executes the provided function when the event occurs.
This is similar to the following code:
<a href="#" onclick="alert('Hello world')">Link</a>
The difference is quite obvious: We don't need to write an onclick for every single element. We have a clean seperation of structure (HTML) and behaviour (JS), just as we seperate structure and behaviour by using CSS.
With this in mind, we explore selectors and events a little further.
jQuery provides two approaches to select elements. The first uses a combination of CSS and XPath
selectors passed as a string to the jQuery constructor (eg. $("div > ul a")). The second
uses several methods of the jQuery object. Both approaches can be combined.
To try some of these selectors, we select and modify the first ordered list in our starterkit.
To get started, we want to select the list itself. The list has an ID "orderedlist". In classic
javascript, you could select it by using document.getElementById("orderedlist").
With jQuery, we do it like this:
$(document).ready(function() {
$("#orderedlist").addClass("red");
});
The starterkit provides a stylesheet with a class "red" that simply adds a red background. Therefore, when you reload the page in your browser, you should see that the first ordered list has a red background. The second list is not modified.
Now lets add some more classes to the child elements of this list.
$(document).ready(function() {
$("#orderedlist > li").addClass("blue");
});
This selects all child lis of the element with the id orderedlist and adds the
class "blue".
Now for something a little more sophisticated: We want to add and remove the class when the user hovers the li element, but only on the last element in the list.
$(document).ready(function() {
$("#orderedlist li:last").hover(function() {
$(this).addClass("green");
}, function() {
$(this).removeClass("green");
});
});
There a lots of other selectors similar to CSS and XPath syntax. More examples and a list of all available expressions can be found here.
For every onxxx event available, like onclick, onchange, onsubmit, there is an jQuery equivalent. Some other events, like ready and hover, are provided as convienent methods for certains tasks.
With those selectors and events you can already do alot of things, but there is more.
$(document).ready(function() {
$("#orderedlist").find("li").each(function(i) {
$(this).html( $(this).html() + " BAM! " + i );
});
});
find() allows you to further search the descendants of the already selected
elements, therefore $("#orderedlist).find("li") is mostly the same as $("#orderedlist
li"). each() iterates over every element and allows further processing. Most methods,
like addClass(), use each() themselve. In this example, html()
is used to get the text of each li element, append some text to it and set it as text of the
element.
Another task you often face is to call methods on the DOM elements that are not covered by jQuery. Think of a form you like to reset after you submitted it successfully via AJAX.
$(document).ready(function() {
// use this to reset a single form
$("#reset").click(function() {
$("#form")[0].reset();
});
});
This code selects the element with the ID "form" and calls reset() on the first
element selected. In case you had more than one form, you could also do this:
$(document).ready(function() {
// use this to reset several forms at once
$("#reset").click(function() {
$("form").each(function() {
this.reset();
});
});
});
This would select all forms within your document, iterate over them and call reset()
for each.
Another problem you might face is to not select certain elements. jQuery provides a filter()
and a not() method for this. While filter() reduces the selection to the
elements that fit the filter expression, not() does the contrary and removes all
elements that fit the expression. Think of a unordered list where you want to select all li
elements, that have no ul child themselve.
$(document).ready(function() {
$("li").not("[ul]").css("border", "1px solid black");
});
This selects all li elements and removes all elements from the selection, that have an ul
element as a child. Therefore all li elements get a border, except the one that has a child ul. The
[expression] syntax is taken from XPath and can be used to filter by child elements and
attributes. Maybe you want to select all anchors that have a name attribute:
$(document).ready(function() {
$("a[@name]").background("#eee");
});
This adds a background color to all anchor elements, that have a name attribute.
Until now, all selectors were used to select childs or filter the current selection. There are situations where you need to select the previous or next elements, known as siblings. Think of a FAQ page, where all answers are hidden first, and shown, when the question is clicked. The jQuery code for this:
$(document).ready(function() {
$('#faq').find('dd').hide();
$('#faq').find('dt').click(function() {
var answer = $(this).find('+dd');
if (answer.is(':visible')) {
answer.slideUp();
} else {
answer.slideDown();
}
});
});
In addition to siblings, you can also select parent elements (also known as ancestors for those more familiar with XPath). Maybe you want to highlight the paragraph that is the parent of the link the user hovers. Try this:
$(document).ready(function() {
$("a").hover(function() {
$(this).parents("p").addClass("highlight");
}, function() {
$(this).parents("p").removeClass("highlight");
});
});
For all hovered anchor elements, the parent paragraph is searched and a class "highlight" added and removed.
Now, with the basics at hand, we want to explore some buzzword aspects.
In this part we write a small AJAX application, that allows the user to rate something, just like it is done on youtube.com.
We need some server code for this. My example uses a php file that reads the "rating" parameter and returns the number of ratings and the average rating. Have a look at rate.php for the server-side code.
As the rating uses AJAX, it won't work without javascript. We therefore generate the necessary markup with jQuery and append it to a container div with an ID of "rating".
$(document).ready(function() {
// generate markup
var ratingMarkup = ["Please rate: "];
for(var i=1; i <= 5; i++) {
ratingMarkup[ratingMarkup.length] = "<a href='#'>" + i + "</a> ";
}
var container = $("#rating");
// add markup to container
container.append(ratingMarkup.join(''));
// add click handlers
container.find("a").click(function(e) {
e.preventDefault();
// send requests
$.post("rate.php", {rating: $(this).html()}, function(xml) {
// format result
var result = [
"Thanks for rating, current average: ",
$("average", xml).text(),
", number of votes: ",
$("count", xml).text()
];
// output result
$("#rating").html(result.join(''));
} );
});
});
This snippet generates five anchor elements and appends them to the container element with the id "rating". Aftewards, for every anchor inside the container, a click handler is added. When the anchor is clicked, a post request is send to rate.php with the content of the anchor as a parameter. The result, that is returned as a XML, is then formatted outputted into the container, replacing the anchors.
If you don't have a webserver with PHP installed at hand, you can look at an online example.
More documentation of the AJAX methods of jQuery can be found here.
With AJAX this simple we can cover quite a lot "Web 2.0". But until now, we lack fancy effects.
Simple animations with jQuery can be achieved with show() and hide()
$(document).ready(function() {
$("a").toggle(function() {
$(".stuff").hide('slow');
}, function() {
$(".stuff").show('fast');
});
});
You can create any combination of animations with animate(), eg. a slide with a fade:
$(document).ready(function() {
$("a").toggle(function() {
$(".stuff").animate({
height: 'hide',
opacity: 'hide',
}, 'slow');
}, function() {
$(".stuff").animate({
height: 'show',
opacity: 'show'
}, 'slow');
});
});
Much fancier effects can be achieved with the interface plugin. Until the plugin is updated to jQuery 1.0 (which is scheduled for next friday by the time of this writing), I won't provide any examples here. Feel free to have a look at the examples at the plugin page.
Just as the interface plugin adds a lot of functionality to jQuery, so do lots of other plugins. The next part shows how to use the tablesorter plugin.
The tablesorter plugin allows sorting of tables on the client side. You only include jQuery and the plugin and tell the plugin which tables you want to sort.
To try this example, open tablekit.html (it has jquery.tablesorter.js included) in your browser and modify customtable.js.
$(document).ready(function() {
$("#large").tableSorter();
});
Try clicking the headers of the table and see how it is sorted ascending on first click and descending on second.
The table could use some row highlighting, we can add those by passing some options:
$(document).ready(function() {
$("#large").tableSorter({
stripingRowClass: ['odd','even'], // Class names for striping supplyed as a array.
stripRowsOnStartUp: true // Strip rows on tableSorter init.
});
});
For more examples and documentation about the available options, at the tablesorter hompage.
Most plugins can be used like this: Include the plugin file and call the plugin method on some elements, passing some optional settings to customize the plugin.
A up-to-date list of available plugins can be currently found on the jQuery site.
Thats it for this guide. If you are now convinced that jQuery might be the right tool for you, conside your next steps.
Writing your own plugins for jQuery is quite easy. If you stick to the following rules, it is easy for others to integrate your plugin, too.
jQuery.fn.fooBar = function() {
// do something
};
jQuery.fooBar = {
height: 5,
calculateBar = function() { ... },
checkDependencies = function() { ... }
};
You can then call these helper function from within your plugin:
jQuery.fn.fooBar = function() {
// do something
jQuery.fooBar.checkDependencies(value);
// do something else
};
jQuery.fn.fooBar = function(options) {
var settings = {
value: 5,
name: "pete",
bar: 655
};
if(options) {
jQuery.extend(settings, options);
}
};
You can then call the plugin without options, using the defaults:
$("...").fooBar();
Or with some options:
$("...").foobar({
value: 123,
bar: 9
});
If you release your plugin, you should provide some examples and documentation, too. Just have a look at some of the great plugins already available.
If you plan to develop more javascript, you should consider a Firefox extension called FireBug. It provides a console (screw alerts!), a debugger and lots more useful stuff for the daily javascript development.
At the time of this writing, the jQuery project architecture is refactored quite a lot. A this temporary address, a much more complete documentation of all jQuery methods is available. This will move soon, therefore often check the jQuery blog for updates.
If you have problems you can't solve, ideas you want to share or just the need to express your opinion on jQuery, feel free to post to the jQuery mailing list.
Thanks a lot to John Resig for this great library! Thanks to the jQuery community!
Think of the puppies!