RSS

Posts Tagged ‘jQuery’

21 Jan 2009

A Comprehensive Introduction to jQuery

Author: Richard Francis | Filed under: Web Development

I love jQuery. It is such a nice, simple, easy to use library and I genuinely enjoy building applications with it. It’s incredibly popular too, which is always a good sign. Amongst its users is the likes of Google, Wordpress, Mozilla, and Technorati.

This tutorial is intended for the jQuery beginner. It helps to have some previous knowledge of the library but I will make sure that I introduce every concept and technique as if I were teaching my Grandmother (well not quite but you get the gist). We will build a simple tabbed interface, introducing you to the jQuery factory function, document traversal & manipulation methods, and even a few clever effects. It’s really very simple :)

See DemoDownload Source Files

The Document Ready Function

In this tutorial we will write all of our jQuery code within a document ready function, which essentially makes sure the page we are working on is ready before we start messing with it! Unlike the native javascript window.onload event, anything you put inside the $(document).ready() function will be executed as soon as the Document Object Model (commonly referred to as the DOM) is ready, rather than when all page contents have loaded.

The Document Object Model, or DOM refers to the ’skeleton’ of a web page. You can view more information about this on the World Wide Web Consortium.

Here is an example of how to use this functionality:

$(document).ready(function(){
	// jQuery it to the max in here!
});

The jQuery Factory Function

No matter what you want to do in jQuery, you will use this function extensively. It comes in the form of a dollar sign and parentheses: $(). By parsing this function a ’selector’ we can select an element on the page, which will create a new jQuery object. We can use all sorts of selector types - CSS, XPath, or even custom.

You can easily select elements on the page using all sorts of selector types including CSS, XPath, or even custom

From this object we can call a method (essentially a function within an object) and use it to perform a task or change a property of the selected element. For example, if we wanted to change the background color of a paragraph that has an ID of “pink”:

$(document).ready(function(){
	// Change the background color of the following paragraph to red
	$('p#pink').css('background-color', '#FF0000');
});

Notice how the selector used here is CSS. At this point it’s also important to highlight jQuery’s chaining capability. As the method (in this case .css()) returns a new jQuery object, we can string these methods together. For example, if we want to change the background color and hide the element we would simply add the .hide() method to the end of the line!

The Interface

So now you have a very basic understanding of how jQuery works as a library, lets create an HTML document in which to build our interface. Start by copying and pasting the following code into the body of your document (within the <body></body> tags).

<div id="container">
	<div id="panels">
		<div class="panel" title="First Panel">
			<h1>First Panel</h1>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
			<p class="emphasis">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
			<p class="red">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		</div>
		<div class="panel" title="The Second Panel">
			<h1>The Second Panel</h1>
			<p class="emphasis">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		</div>
		<div class="panel" title="Third Panel">
			<h1>This is the Third Panel</h1>
			<p class="red">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		</div>
		<div class="panel" title="Hello World">
			<h1>Hello World</h1>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		</div>
	</div>
</div>

So we now have the content for our panels. Notice that there are no tabs/links included in the content. The tabs will be dynamically generated by jQuery, the beauty of this being that panels can be removed and/or added to the interface without changing any links or code for tabs.

The beauty of these tabs is that as panels are added and removed, the number of tabs will change accordingly as they are generated dynamically

Now we need to style the page to make it a little easier on the eye. Either embed the following CSS in the page or link to it in an external style sheet.

/* Set all elements to a default margin &amp;amp;amp; padding of 0 */
* {
	margin:0;
	padding:0;
}
body {
	background-color:#FFFFFF;
	font-family: Arial, Helvetica, sans-serif;
	font-size:12px;
}
div#container {
	width:600px;
	margin:40px auto;
}
div#panels {
	border:2px solid #000000;
	padding:20px;
}
p {
	line-height:1.5em;
	margin-bottom:1em;
}
a.tab {
	display:inline-block;
	background-color:#000000;
	color:#FFFFFF;
	padding:5px 10px;
	text-decoration:none;
	margin-right:3px;
}
a.tab:hover {
	background-color:#333333;
}
a.tab-active {
	display:inline-block;
	background-color:#FF0000;
	color:#FFFFFF;
	padding:5px 10px;
	text-decoration:none;
	margin-right:3px;
}
p.emphasis {
	font-style:italic;
}
p.red {
	color:red;
}

So just to clarify, if you test your page you should currently see a centered box with a thick black border containing 4 headings and a total of 7 paragraphs. 2 of these paragraphs will be red and 2 will be emphasized (italic).

Lets Write Some jQuery!

For this tutorial we will write all our JavaScript within the same page, inside the <head></head> tags (the page header). Before we write anything though, we will of course have to include the jQuery library. You can download it here, or simply link straight to the jQuery site to retrieve the latest version. You should use this method only for development.

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>

Now I think the best way for me to explain how our jQuery code will work is to include the whole lot below and then take you through it in bite size chunks. So here it is (be sure to include it within <script type="text/javascript"></script> tags).

$(document).ready(function(){
	// We can use this object to reference the panels container
	var panelContainer = $('div#panels');
	// Create a DIV for the tabs and insert it before the panel container
	$('<div id="tabs"></div>').insertBefore(panelContainer);

	// Find panel names and create nav
	// -- Loop through each panel
	panelContainer.find('div.panel').each(function(n){
		// For each panel, create a tab
		$('div#tabs').append('<a class="tab" href="#' + (n+1) + '">' + $(this).attr('title') + '</a>');
	});

	// Determine which tab should show first based on the URL hash
	var panelLocation = location.hash.slice(1);
	if(panelLocation){
		var panelNum = panelLocation;
	}else{
		var panelNum = '1';
	}
	// Hide all panels
	panelContainer.find('div.panel').hide();
	// Display the initial panel
	panelContainer.find('div.panel:nth-child(' + panelNum + ')').fadeIn('slow');
	// Change the class of the current tab
	$('div#tabs').find('a.tab:nth-child(' + panelNum + ')').removeClass().addClass('tab-active');

	// What happens when a tab is clicked
	// -- Loop through each tab
	$('div#tabs').find('a').each(function(n){
		// For each tab, add a 'click' action
		$(this).click(function(){
			// Hide all panels
			panelContainer.find('div.panel').hide();
			// Find the required panel and display it
			panelContainer.find('div.panel:nth-child(' + (n+1) + ')').fadeIn('slow');
			// Give all tabs the 'tab' class
			$(this).parent().find('a').removeClass().addClass('tab');
			// Give the clicked tab the 'tab-active' class
			$(this).removeClass().addClass('tab-active');
		});
	});
});

So there’s the full code and now here’s the explanation!

Creating A New DIV

// We can use this object to reference the panels container
var panelContainer = $('div#panels');
// Create a DIV for the tabs and insert it before the panel container
$('<div id="tabs"></div>').insertBefore(panelContainer);

Here we are first declaring a variable to store a jQuery object (the jQuery factory function returns a jQuery object). We will use this variable regularly throughout our code so it makes sense to do this because we can then repeatedly call and pull methods from this same variable. It’s easy to remember too!

We then use this variable to create the new DIV. Notice that when inserting something into the DOM the method used is called from the object containing the new code. The element that you wish to insert your code before is then parsed to this method.

Create The Tabs

// Find panel names and create nav
// -- Loop through each panel
panelContainer.find('div.panel').each(function(n){
	// For each panel, create a tab
	$('div#tabs').append('<a class="tab" href="#' + (n+1) + '">' + $(this).attr('title') + '</a>');
});

This part of the code creates a tab for every panel. On line 3 in the above snippet we find every DIV with the ‘panel’ class that is inside the panelContainer (’div#panels’) and perform a function for each one, by calling methods from the panelContainer variable created at the beginning of the script. .find() will find elements inside the parent element that match the selector expression. .each will execute the script that is parsed to it however many times it finds the element that it’s chained to. In this case, it is chained to the panels so it will execute the script 4 times. If you include a variable (in this case ‘n’) in the function that is being executed, it will then increment by 1 every time the script runs. It’s initial value will be 0.

In line 5 of the snippet above we are appending a tab to the DIV that we created at the beginning of the script (’div#tabs’) using the .append() method. Notice how we include a location hash in the href attribute (n+1). The href of the first tab will be #1, the second #2, and so forth. We will get to the purpose of doing this in the next section.

You will also see how $(this).attr('title') is used to get the title of the link. $(this) returns the parent element from which it is being called, in this case whichever panel it is currently looping through. The attribute method can be used in two ways; to assign an attribute or retrieve an attribute. In this case we are retrieving the ‘title’ attribute from the parent panel. If we wanted to assign an attribute to the parent element, we would parse two parameters to the method as opposed to one:

$('a#theID').attr('href', 'http://www.blemble.com');

Determine The First Tab To Display

// Determine which tab should show first based on the URL hash
var panelLocation = location.hash.slice(1);
if(panelLocation){
	var panelNum = panelLocation;
}else{
	var panelNum = '1';
}

This part of the code is actually pretty simple and doesn’t use jQuery at all. It simply grabs the location hash from the URL, removes the hash, and stores the number in a variable (actually it’s a string datatype but it doesn’t matter for what we need it for). If there is no hash present then it will default to 1. This functionality is not really necessary but when I think it’s quite useful. It enables support for a direct link to a specific tab. I can link to the second tab, the first tab, or even the fourth tab directly!

Show The Correct Panel!

// Hide all panels
panelContainer.find('div.panel').hide();
// Display the initial panel
panelContainer.find('div.panel:nth-child(' + panelNum + ')').fadeIn('slow');
// Change the class of the current tab
$('div#tabs').find('a.tab:nth-child(' + panelNum + ')').removeClass().addClass('tab-active');

Okay, we start this snippet by hiding all panels within the panel container (panelContainer) using the .hide() method. We could alternatively use .css('display', 'none'), it’s just that .hide() is a lot shorter!

On line 4 we then use the ‘nth child’ selector to find the panel that we need to display. We parse it the variable that we declared in the last section and it finds the correct panel. The .fadeIn() method is then called and you guessed it, the correct panel will fade in! See how easy it is to use effects!? Note that if you want to execute a a function when the effect is complete (a callback function) then you simply parse a function into the effect method!

panelContainer.find('div.panel:nth-child(' + panelNum + ')').fadeIn('slow', function(){
	// Do this when the animation finishes
});

After this, we select the #tabs DIV and find the tab that corresponds to the location hash using the ‘nth child’ selector. We then remove the current class of this element (.removeClass()) and add the class ‘tab-active’, which is specified in our style sheet. This will give the current tab a red background.

// What happens when a tab is clicked
// -- Loop through each tab
$('div#tabs').find('a').each(function(n){
	// For each tab, add a 'click' action
	$(this).click(function(){
		// Hide all panels
		panelContainer.find('div.panel').hide();
		// Find the required panel and display it
		panelContainer.find('div.panel:nth-child(' + (n+1) + ')').fadeIn('slow');
		// Give all tabs the 'tab' class
		$(this).parent().find('a').removeClass().addClass('tab');
		// Give the clicked tab the 'tab-active' class
		$(this).removeClass().addClass('tab-active');
	});
});

The final snippet of code assigns .click() events to each tab and thus determines how the application will respond to user actions. So as you can see, we loop through each tab using .each() and parse the method a function. We then assign click events to each tab and parse this method a function, which contains the actions we want it to perform.

You will notice that the code inside this function is very similar to that of the last code snippet. We first hide all of the panels, then show the required panel using the :nth-child selector. Then we take care of the tab classes and change them as necessary in order to make it clear to the user which tab is currently active.

Download the source code here

And that’s it, you have just made your first jQuery application and learned some cool techniques on the way too! Let me know if you found this tutorial useful and leave a comment.