Tuesday 4 August 2009

Getting Started With jQuery

What Is jQuery?

jQuery is a free JavaScript library that allows developers to leverage the HTML DOM in a much easier and intuitive way than was previously available with native JavaScript functions. A huge array of functions are available within the library for animating things, fading in and out, sliding in and out, getting and setting text, values etc. etc.

Where to Get jQuery
You can download jQuery at http://code.google.com/p/jqueryjs/downloads/list.

There are several variations of the core library available, but I would recommend that you download the following versions if you're developing using Visual Studio.
  1. jquery-1.3.2.min.js (a minified version of the library, stripped of all whitespace, and to be used for release versions of your code.)

  2. jquery-1.3.2-vsdoc2.js (a version of the library that will provide intellisense for Visual Studio) NOTE: You will need to install service pack 1 for Visual Studio 2008 if you wish to benefit from the intellisense - it's definitely worth it...
Getting Started With jQuery
Referencing the jQuery Library
It's easy to import and use jQuery in your projects. I usually create a folder off the root of my web sites called global, which then contains sub folders for css, js, and any other globally shared files.

Then, in all pages that need to use jQuery simply include the following script block:

<script src="global/js/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script>

The above script block provides a reference to the Visual Studio formatted library, but some browsers don't render some of the fading or animating effects properly using this library so I usually include a linke to both versions of the library, with the minified version commented out while I'm developing. I then comment the VS version of the library out and the minified version of the library in when I come to test or release the code, as follows:

During Development
<script src="global/js/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script>

<%--<script src="global/js/jquery-1.3.2.min.js" type="text/javascript"></script>--%>
During Testing and for Release


<!--<script src="global/js/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script>-->
<script src="global/js/jquery-1.3.2.min.js" type="text/javascript"></script>


For example,

$(document).ready(function() {
//Code to be called when the document is loaded
});

The jQuery Object

The jQuery object is basically a JavaScript function. The standard notation for calling the jQuery object is :

jQuery(String selector, jQuery context);
Using the above noted shortcut this can be shortened to
$(String selector, jQuery context);
First of all, you MUST understand that the jQuery function returns a jQuery object, NOT an HTML DOM object. However, this is rarely an issue as the jQuery object returned is a lot richer than the HTML DOM object it refers to.

The first argument of the jQuery function is a selector, basically an instruction for locating the item you want to return. The range of selectors available are many and diverse and sufficiently flexible to reach just about all objects on the page.

For a complete list of the selectors available have a look at the on-line documentation here.

The ready() function

Traditionally, developers have had to use the onload event of the window object before they've been able to perform operations on the HTML DOM, but this event only fires after all images have downloaded. jQuery provides a function called ready that fires when the page has loaded and is ready for manipulation.

In fact, this is usually the starting location for all of your jQuery as it's the place that you hook into jQuery.

Learning from Example

Having dealt with the basics let's talk through a basic example that demonstrates how this links together. I'll give you the complete picture first, then I'll talk through it in more detail.


   1:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

   2:   

   3:  <script src="global/js/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script>

   4:  <!--<script src="global/js/jquery-1.3.2.min.js" type="text/javascript"></script>-->

   5:   

   6:  <script language="javascript" type="text/javascript">

   7:      $(document).ready(function() {

   8:          $('.main > :button').toggle(function() {

   9:              $('.content').slideDown('slow');

  10:          }, function() {

  11:              $('.content').slideUp('slow', function() {

  12:                  alert('div is now hidden');

  13:              });

  14:          });

  15:      });

  16:  </script>

  17:   

  18:  <html xmlns="http://www.w3.org/1999/xhtml">

  19:  <head>

  20:      <title>jQuery Demo</title>

  21:      <link href="global/css/jQueryStyleSheet.css" rel="stylesheet" type="text/css" />

  22:  </head>

  23:  <body>

  24:      <div class="main">

  25:          This is some text inside the main div.  A button allows me to show and hide the content block.<br />

  26:          <input type="button" value="Toggle Content" />

  27:              <div class="content">

  28:              This is a content block...

  29:              </div>

  30:      </div>

  31:  </body>

  32:  </html>




The first thing to notice about the above example is the fact that everything is contained inside the ready function. To explain... the parameter that is passed to the ready function is a function itself. Similarly, the two parameters passed to the toggle function (which will be explained in a moment) are also functions. JavaScript allows the use of anonymous functions, something that will still be fairly new to .NET developers. So, the script that has been written as:

    $(document).ready(function() {

        $('.main > :button').toggle(function() {

            $('.content').slideDown('slow');

        }, function() {

            $('.content').slideUp('slow', function() {

                alert('div is now hidden');

            });

        });

    });


could also have been written as follows, and would probably be more readable to people new to JavaScript:


    $(document).ready(onLoad);

 

    function onLoad(){

        $('.main > :button').toggle(showContent, hideContent);

    }

 

    function showContent() {

        $('.content').slideDown('slow');

    }

 

    function hideContent() {

        $('.content').slideUp('slow', hideCallback);

    }

 

    function hideCallback() {

        alert('div is now hidden');    

    }  


However, as you'll notice, this occupies a lot more space and actually, once you become familiar with the anonymous function style of working, is more difficult to read because you have to shift your focus from where the function is called to see what it performs. The anonymous method notation keeps the logic of the function and the location of its call together. Of course, if you find yourself copying and pasting function logic you should automatically wrap that logic in a named function to avoid dupllicating code.

Now, to explain what's happening...

When the document is ready, the button located in the main content block has the toggle function bound to it. Now, when the button is clicked a function runs to slide the content div down, displaying it and when clicked again a second function runs to slide the content div up, hiding it. The jQuery documentation describes the toggle function as follows:

"Toggle between two function calls every other click. Whenever a matched element is clicked, the first specified function is fired, when clicked again, the second is fired. All subsequent clicks continue to rotate through the two functions."

Selectors

Locating the button was quite easy using the selector: '.main > :button'.

jQuery borrows some of its selector notation from CSS. So, if an element uses a class, as the div in question does, the element can be located using the name of the class preceded by a "." character. Similarly, if an element is named it can be accessed by using the id slector. For example, if the element had an id of "mainDiv" it would be located using the selector

$('#mainDiv')


The ">" character locates a child element. In this case, the button is located within a div, so the ">" character is used after the selector for the div. Finally, form fields can be accessed using special notation such as ":button", ":text", ":radio", ":submit" etc.

So, the '.main > :button' selector transliterates as "return me all elements that are a button within an element that uses the css class 'main', as a jQuery object."

Again, here we have an important point to note... The jQuery object returned may reference several objects. So, if there were several buttons inside the 'main' div the jQuery object returned would refer to all of them. They would all therefore have a toggle function bound to them and would all perform the same actions when clicked. In some cases this might be desired. For example you might want a function to change the borders of all the divs on a page. In fact, let's add a second button to the main div that will perform this action when clicked. The main div now looks like this:

<div class="main">
This is some text inside the main div. A button allows me to show and hide the content block.<br />
<input type="button" value="Toggle Content" />
<input type="button" value="Change borders" />
<div class="content">
This is a content block...
</div>
</div>

This example gives us a significant cause to update our jQuery code because, as just described we only want the first button to perform the show/hide of the content div, and the second to perform the change of the borders. We could get around this by giving the buttons distinct id's and then using the id selector notation as described above. In practice that's what I would do, as it would allow us to move the button around the form and our jQuery will still work. However, to demonstrate another type of selector I'm not going to do that this time.

Let's look at how we modify our existing jQuery code to specify only the first button in the main div.

$('.main > :button:first')

Our selector has now been modified to only return the first child button of the main div. So, you would probably guess that you would use a :second, :third, :fourth selector to return the second, third and fourth buttons - but you'd be wrong.... The people at jQuery obviously saw themselves getting into bother if they went down that track. So, they came up with another selector :eq(index) that allows the return of anything after the first. So, to access the second button we'd use the following selector

$('.main > :button:eq(1)')

Alternatively, because the second button in the main div is also the last button in the div the selector

$('.main > :button:last')
could also be used.

So the jQuery code for changing the borders of the divs would look like this:

$('.main > :button:last').click(function() {
$('div').css('border', 'solid 1px black');
});
As the penny is probably starting to drop by now you'll probably see straight away that this code is binding a function to the returned object's click event. What happens when the object is clicked is also probably becoming quite clear... A jQuery object referencing all of the divs on the page has the css function called on it that sets the referenced elements' borders to solid black 1px wide.

Remember that jQuery selector notation borrows from CSS. So, the jQuery to reference a div is simply 'div'. Similarly, selecting all table cells in a table would be achieved with 'td' and so on.

Functions

There are many functions available within the core library. It would be foolish of me to try and lit them all in this article when perfectly adequate documentation exists in the documentation.

Extensions to jQuery

The array of functions available on a jQuery object is vast and expanding all of the time with the availability of plugins, or extensions, to the core library. Plugins can be found at http://plugins.jquery.com and most come with adequate documentation and even a demo of it in action. Beware, though, because most of the plugins are written by members of the general programming community and as a result won't all perform as expected.

Conclusion

Trying to encompass all of jQuery in a single article is a fool's errand. However, getting started with it is probably the biggest obstacle and I hope this has helped you to overcome that obstacle.

No comments:

Post a Comment