Screencasts

Introduction to jQuery

Download Files ↓

Show Notes

Overview

This screencast will show you how to use some of jQuery’s core functionality, including accessing attributes, manipulating HTML, transversing the document, applying effects and handling events. We’ll show you how to setup a page with an article and two forms (sign in and sign up) that dynamically hides and reveals the forms, and compares the password and password confirmation fields, along with notifications for the user.

What You'll Learn:

  • How to access attributes
  • How to Manipulate HTML
  • How to Transverse the document
  • How to apply effects
  • How to handle events

Links

Script

Introduction

This screencast will give you an introduction to jQuery. We’ll explain what jQuery is, why you’d use it, and then how you’d use it in your code. After finishing this screencast you’ll be able to use the core functionality of jQuery in your projects, and be on your way to writing unobtrusive javascript in powerful web applications.

A little web development history...

To fully appreciate jQuery, let’s quickly review some web development history:

Back in the early days of the web, people used tables and in-line styling such as the font tag to build websites.

<font face="verdana" color="green">Styled text</font>
<table width="600" border="1">
  <tr>
    <td>Main Content</td>
    <td>Side Bar</td>
  </tr>
</table>

This made it difficult for search engines and screen readers to navigate the html markup.

More recently CSS evangelists started telling us we should have a separation between markup and layout. This enabled web developers and designers to build the same webpage with separate styling and cleaner markup.

<div class="main_content">
  <p>Main text</p>
</div>
<div class="side_bar">
  <p>More text</p>
</div>
.main_content p {
  font-size: 12px;
}
.side_bar p {
  font-size: 10px;
}

This had a number of benefits. It improved the experience for screen readers and search engines, but it also reduced load time with smaller html files and styling in only one file. This also made websites more manageable.

As broadband speeds became more common, websites could become more complex, using languages like javascript to deliver more desktop-like experiences on the web. Originally javascript would be included directly in the HTML markup.

<a href="javascript:window.open('popup.html')">Popup</a>

This started cluttering the HTML, a problem almost identical to the pre-CSS inline styling era. The inclusion of in-line javascript broke screen readers, hindered readability by search engine spiders, and often broke in other browsers.

As before, leaders in the web developer community advocated better ways of including javascript into web applications. This separation of behavior from the HTML markup is called "Unobtrusive Javascript.” Just as the CSS evangelists told us that there should be a separation of layout from markup, JavaScript evangelists told us there should be a separation of behavior from markup.

Obtrusive to Unobtrusive JavaScript

Let’s say you want to open a popup in a new window when clicking a link. There are several ways you can go about this. One way would be to put a hash in the href attribute and move the javascript code into the onclick attribute. If javascript is disabled, the user is left stuck on the page.

<a href="#" onclick="javascript:window.open('popup.html'); return false;">Popup</a>

Here is the code working correctly in a browser with Javascript enabled. But as you can see, if javascript is disabled, the user is left stuck on the page.

A better way would be to include the popup file name in the href attribute, as well as including the javascript in the onclick attribute.

<a href="popup.html"  onclick="javascript:window.open('popup.html'); return false;">Popup</a>

This way, if the user disables javascript, they can still access the popup, but in the same window as the previous page. However, if we had several links like this, we would be duplicating a lot of the same javascript code.

CSS enables us to describe our documents layout by assigning classes to elements. We can use this technique to apply behavior to elements in an efficient manner. The best practice would be to add a descriptive class (such as "new_window”) to our link.

<a href="popup.html" class="new_window">Popup</a>

In order apply our desired behavior to the link, we need to implement the behavior in javascript.

First we need to apply the functionality when the document loads.

window.onload = function() { }

Then we need to iterate through the document’s anchors or links, looking for our "new_window” class.

window.onload = function() {
  var anchors = document.getElementsByTagName('a');
  for(var i = 0; i < anchors.length; i++) {
    var anchor = anchors[i]; 
    if(anchor.className == "new_window") { 
    } 
  }
}

The reason we are getting elements by tag name, and then checking the class, is because some older browsers such as IE6 don’t have the method getElementsByClassName, so we have to cater to the lowest common denominator.

Once we’ve found the link in question, we need to add the desired functionality:

window.onload = function() {
  var anchors = document.getElementsByTagName('a');
  for(var i = 0; i < anchors.length; i++) {
    var anchor = anchors[i]; 
    if(anchor.className == "new_window") { 
      anchor.onclick = function(){
        var href = this.href;
        window.open(href);
        return false;
      }
    } 
  }
}

return false tells the browser not to load the popup page in the current window. When javascript is switched off, the link will work as a standard link. This is known as graceful degradation.

But this code is far from perfect. There are a number of problems. The window.onload handler gets executed after the page and any images have loaded. This means your application may not look as desired until the browser has finished loading the assets. This code overrides any existing load or click handlers, which could be in conflict with other behaviors. This could be a problem if you’re working on a project with two developers, and you’re both applying behavior the same link. If this were the case, the last behavior executed would win.

The way we are checking for the classes applied to our links is very brittle. It wouldn’t work for links with more than one class applied to it. For example, our code wouldn’t work for a link with a class attribute "new_window external_link".

The way to overcome these issues is to use jQuery. jQuery uses the same CSS selectors and syntax you’re probably already using to style your pages, so you almost already know how to apply behavior to your markup using jQuery. You don’t have to worry about cross-browser compatibility, since jQuery selectors work in all modern browsers including IE6. It’s also compatible with other javascript frameworks, so you can use it alongside things such as DWR and prototype.

$("a.new_window").click(function(){
  window.open(this.href);
  return false;
});

The behavior is ready faster than with traditional javascript, since jQuery provides an onready handler which executes when the html file is downloaded, but the images haven’t. The onload handler, used by traditional javascript, executes after the images have downloaded. So jQuery gets your behavior ready in milliseconds, as opposed to seconds.

As you’ll see, jQuery allows you to write less code, and do more.

Using jQuery in Your Projects

To use jQuery in a project you first need to visit the jQuery website. As you can see there are two different versions. One that is 24 kilobytes for "Production” and 155 kilobytes for "Development”. "Development” is an uncompressed version of the jQuery whereas the "Production” has gone through a compression processes also known as minification. Minifying a JavaScript file means that all unnecessary whitespace, new line characters and comments are removed. The minification process can also pass the JavaScript file through an obfuscation process to reduce the amount of data transferred over the wire by shortening variables and function names.

When you download the "Production” version of jQuery you’ll notice that the size of the file is not 24KB it’s around 70KB. This is not a mistake. The jQuery minified version is actually not 24 KB but 70KB. However if you go back to jQuery.com the "Production” version doesn’t just say minified, it also says gzipped.

Gzipping is a process for compressing plain text files such as HTML, CSS and JavaScript between web server and web browser. When a browser makes a request it sends a header to say that it accepts gzipped compressed content. The web server, such as Apache, if configured correctly recognizes the request header and serves up the compressed file. The browser in turn decompresses the requested file. This conserves bandwidth and improves load times. Hence if gzip compression is switched on, the "Production” jQuery is 24 KB over the wire. Most shared hosts have this set up already so you don’t need to worry. If you have your own self managed dedicated server you probably need to set it up yourself. But this is beyond the scope of this screencast, so if you need to do that look at the documentation for your web server.

However, there is an alternative to serving up the jQuery library yourself. Google has provided all major javascript libraries, including jQuery, on their content distribution network, with all the appropriate compression and caching switched on. So you don’t need to worry about this. The other advantage of this is that many other sites use Google’s AJAX Libraries API to serve jQuery. What this means is that if a user has visited a site already using Google’s served up jQuery it will be cached on their machine thus reducing load times on your site. The only reason you wouldn’t want to use this is if you are using jQuery in an offline or sensitive environment, such as an internal intranet site, and you don’t want be to going out on the web to include javascript.

Once you’ve downloaded the version of jQuery you want or found the URL from Google, all you need to do is include the jQuery file in your html somewhere.

This can be done in two places:

The first place is at the top of the page in the head tag. This means that you’ll have to use the ready callback to execute jQuery or JavaScript code.

First, we are including Google’s hosted jQuery. The reason we have two script tags is because we are specifying a source for the first one, which means that the contents of this tag would not get evaluated. To get around this, we include another tag and put our javascript in there.

It looks like this:

...
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $("p").text("Hello jQuery");
         });
    </script>
</head>
<body>
    <p></p>
</body>
...

When the HTML document has loaded and is ready to be manipulated by jQuery the anonymous function or handler gets executed and the code is run.

Or in short hand:

...
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function(){
            $("p").text("Hello jQuery");
        });
    </script>
</head>
<body>
    <p></p>
</body>
...

You can remove (document).ready and it will still work. Either way is acceptable.

The second way of including jQuery is at the bottom of the page, just before the closing body tag. But this time you don’t need to use the ready event because the page is already downloaded and is ready to be manipulated.

So now it looks like this:

...
<head></head>
<body>
    <p></p>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script> 
    <script type="text/javascript">
        $("p").text("Hello jQuery");
    </script>
</body>
...

This way is recommended to increase page load speeds giving users a better experience.

As you can see with both ways of including jQuery, the paragraph tag gets populated with the text "Hello jQuery”.

Now lets move on to the main code example.

Form Example

Here is an example web page with two forms and an article.

This code for this example is available in the show notes.

In this example we’re going to cover how to hide the forms when the page loads, setup jQuery functions to reveal the appropriate form when a link is pressed, and show some basic validation on the form. You’ll learn now to select, manipulate and transverse your html document using jQuery. So let’s get to it.

Open the index.html file in your browser. As you can see, we have two links, sign in and sign up. They link to their respective forms. Open the index.html file in your editor of choice.

...
<ul>
    <li><a href="#sign_in">Sign In</a></li>
    <li><a href="#sign_up">Sign Up</a></li>
</ul>
...

As you can see we have two links in an unordered list, followed by two forms, sign in and sign up, and then an article.

...
<div id="sign_in">
    <h2>Sign In</h2>
    <form action="/sign_in" method="post">
        <p>
            <label for="sign_in_username">Username</label>
            <input type="text" name="sign_in_username" id="sign_in_username" />
        </p>
        <p>
            <label for="sign_in_password">Password</label>
            <input type="password" name="sign_in_password" id="sign_in_password" />
        </p>
        <p>
            <input type="submit" value="Sign In" />
        </p>
    </form>
</div>

<div id="sign_up">
    <h2>Sign Up</h2>
    <form action="/sign_up" method="post">
        <p>
            <label for="sign_up_username">Username</label>
            <input type="text" name="sign_up_username" id="sign_up_username" />
        </p>
        <p>
            <label for="sign_up_password">Password</label>
            <input type="password" name="sign_up_password" id="sign_up_password" />
        </p>
        <p>
            <label for="sign_up_confirmation">Confirm Password</label>
            <input type="password" name="sign_up_confirmation" id="sign_up_confirmation" /> <span></span>
        </p>
        <p>
            <input type="submit" value="Sign Up" />
        </p>
    </form>
</div>
...

The forms are very basic, with a small number of fields. If you’d to familiarize yourself with the html, feel free to pause the video at this point and review the code.

Obviously, showing the two forms on the page like this isn’t desirable. Let’s use jQuery to hide the forms. First we need to add jQuery to our page, then create an application.js file and include that file in our document.

In order to identify the form containers in jQuery, we need to select them using CSS. In this case, we could use the div ids to identify each form container. But in this example we’re going to setup a class to group the containers together to apply the same behavior. This allows us to add more forms in the future without modifying the javascript or jQuery, while still getting the desired effect.

So let’s add class=”forms" to each of the form divs.

<div id="sign_in" class="forms">
    <h2>Sign In</h2>
    ...
</div>

<div id="sign_up" class="forms">
    <h2>Sign Up</h2>
    ...
</div>

Because we are including application.js at the end of the file, we don’t need to manually add the onready callback. All we need to do is put in the jQuery behavior we want to be executed as soon as the file is loaded.

To hide the forms, we simply add $(".forms").hide();  to our application.js file.

$(".forms").hide();

As you can see, when we refresh the page in our browser, the forms are now hidden. When we click on these links however, nothing happens. We need to add the behavior to reveal the forms.

We need to add a click event listener to the link elements contained within the unordered list and list items. In order to check that we are correctly binding this function to the link elements, let’s add a simple alert to verify.

...
$("ul li a").click(function(){
    alert($(this).attr("href"));
});

In the function, this refers to the DOM element in which the click handler has been triggered. In order to get the jQuery representation of the DOM element, we need to enclose this in parentheses with a dollar sign in front of it. Now that we have a jQuery representation of the object, we can now use jQuery methods on it. The attr method can be used to access the value of a given attribute. In this case, href.

So let’s check this out in the browser to see if it’s working correctly. Ok, great, clicking on the links gives us the desired executed code. If you notice, the hash link is also exactly the same as the CSS selector for the relevant form’s container. So let’s now select that using jQuery, and use the jQuery show method in order to reveal it. For the sake of convenience and readability, we will create a local variable idToShow. Then we need to get a jQuery representation of the element with that id by adding the jQuery parentheses around idToShow. We then add .show(), and as you can see it shows the correct form.

...
$("ul li a").click(function(){
    var idToShow = $(this).attr("href");
    $(idToShow).show();
});

But if you notice, when we click the other link, it now shows both of the forms. Ideally, we’d want the other form’s container to hide. In order to do this, we create a local variable "siblings” and assign it $(idToShow).siblings(). On the next line we write siblings.hide(); in order to hide the siblings.

...
$("ul li a").click(function(){
    var idToShow = $(this).attr("href");
    $(idToShow).show();
    var siblings = $(idToShow).siblings();
    siblings.hide();
});

If we launch this in the browser now, we’ll see that when we click on a button, the entire page is hidden apart from our selected form. This obviously isn’t what we want, so let’s go back to our .js file and be more specific in the siblings that we want to hide. So within the siblings function, we can pass in the CSS selector we want to hide, in this case ".forms” .

...
$("ul li a").click(function(){
    var idToShow = $(this).attr("href");
    $(idToShow).show();
    var siblings = $(idToShow).siblings(".forms");
    siblings.hide();
});

Thinking back to our decision to use a class "forms” to identify our form containers, this has made this a trivial exercise. If we just used the ids of the containers, we would have to implement a much more complex method to hide the form containers.

Now that we’ve added the .forms CSS selector to our siblings function, we can see in our browser that the desired functionality of hiding the other form is working. But the browser is jumping to the top of each form container when clicked. To prevent this, all we need to do is add return false to the end of our function, which overrides the default browser behavior for a link.

...
$("ul li a").click(function(){
    var idToShow = $(this).attr("href");
    $(idToShow).show();
    var siblings = $(idToShow).siblings(".forms");
    siblings.hide();
    return false;
});

jQuery enables us to chain methods together. So these lines can be written in fewer lines. At the end of the show method, we can add siblings(".forms") followed by .hide(). What this is doing is getting the siblings of the container we want to show, and hiding them.

...
$("ul li a").click(function(){
    var idToShow = $(this).attr("href");
    $(idToShow).show().siblings(".forms").hide();
    return false;
});

Now lets add a way to notify the user when the password fields don’t match. To do this we need to add a jQuery event listener to our password confirmation field. We need to watch for key strokes on the field and compare it with the first password field. The keyup event is triggered after the key is pressed. Once again we need to implement an anonymous function to be triggered on keyup. On any type of input you can call val() to retrieve the value of that particular input. So here we need to see if the two passwords match or not. If they don’t match we’ll add a CSS class called error to notify the user. It could be named anything, we’re just using something sensible.

...
$("#sign_up_confirmation").keyup(function(){
    if ( $(this).val() != $("#sign_up_password").val() ) {
        $(this).addClass("error");
    }
});

We need to remember to add some styling in our CSS to alert the user.

...
input.error {
    border: 50x solid #f00;
}

So now when we type test in to our password field and test1 in our confirmation we see the error class being applied. Great. But this isn’t quite complete because when we correct the password field the error class isn’t removed.

To do this we just need to include an else statement to remove the error class when it matches. Simple.

...
$("#sign_up_confirmation").keyup(function(){
    if ( $(this).val() != $("#sign_up_password").val() ) {
        $(this).addClass("error");
    } else {
        $(this).removeClass("error");
    }
});

Here we can see that when the fields match, the error class is being removed correctly.

Finally we want to include a text message to say that the passwords don’t match. First lets add an empty span tag after our confirmation input in the HTML. In order to get the span from the confirmation field we can transverse, or move through the document by using the next() method. This will return the span element for you to manipulate. All we need to do now is add the text() method to the returned span with the strings we want it to display. So we’ll display "Passwords don’t match” when they don’t match, and an empty string "" when they do match. Again we’re chaining methods together, but this could be written over many lines. But chaining methods like this makes the code much easier to read.

...
$("#sign_up_confirmation").keyup(function(){
    if ( $(this).val() != $("#sign_up_password").val() ) {
        $(this).addClass("error").next().text("Passwords don't match.");
    } else {
        $(this).removeClass("error").next().text("");
    }
});

Hit refresh and we have our fully working example.

Conclusion

In this jQuery introduction we’ve covered several main areas: accessing attributes, manipulating html, transversing the document, applying effects and handling events.

Thank you for your time and we hope you’ll have fun putting your new skills to use.

If you have any questions, feedback or suggestions please email feedback@screencasts.org.

Be sure to follow us on Twitter, subscribe to our RSS feed and newsletter to be notified about jQuery and other web development screencasts as they become available. See you next time.

← Latest Episodes

blog comments powered by Disqus