Six Things Every jQuery Developer Should Know

Elijah Manor | November 13, 2009


This article is not intended to be a beginner’s guide to jQuery development. Instead, it  examines some of the more nuanced situations you encounter during jQuery development. Here are some assumptions I’ve made about what you should know before reading this article:

  • Basic understanding of JavaScript and the DOM
  • How to use common jQuery CSS selectors (example:  $('div a').fadeOut('slow');)
  • A working knowledge of basic jQuery functions (such as  fadeOut, animate, slideUp, and so on)
  • An understanding of callback functions and anonymous functions.

If you are not familiar with these concepts, you might consider brushing up with a jQuery tutorial such as Jeffrey Way's jQuery for Absolute Beginners video series, which contains 15 professional beginner videos that bring any developer up to speed with jQuery.

1. What Is This?

After I learned the basics of jQuery and was amazed by how much is possible with so little code, I started branching out and tried more complicated functions and plug-ins. However, before long I was confused about the concept of the thiskeyword. If you are a beginner, this can be quite confusing if you don’t understand it correctly. Sometimes it refers to a DOM element and other times it can refer to a jQuery object. Without knowing how to tell the difference, your work is more like an exercise in guessing than programming.

Under normal circumstances, the this keyword refers to a DOM element. It is most commonly used inside a callback function, such as when binding to an event, iterating over elements with the each function, using animations, using filters, and various other functions.

Numerous functions inside jQuery can accept callback functions that you might not have noticed before. For example, jQuery has two functions for fadeOut. One function takes only a speed argument, but the other function accepts a speed argument and a callback function. After the DOM selection fades out, the callback function provided is triggered, and at that point the this keyword refers to the selected DOM element. If more than one element is selected to fadeOut, the callback is triggered after the corresponding element fades out. Here are several examples of using the this keyword:

//Binding to an event
$('a').click(function() {
   //this refers to the anchor DOM element
   console.log("this.href = '" + this.href + "'");
//Iterating over elements from a jQuery selection
$('a').each(function() {
   //this refers to the anchor DOM element
   console.log("this.href = '" + this.href + "'");
//Fading DOM elements from a jQuery selection
$('a').fadeOut('slow', function() {
   //this refers to the anchor DOM element that was just faded out
   console.log("this.href = '" + this.href + "'");

As you can see, in most scenarios involving the this keyword, it refers to an actual DOM element. However, the main area in which you need to be careful with the this keyword is when you write a jQuery plug-in. The this keyword immediately inside a jQuery plug-in refers to the jQuery object from the selector used when calling the plug-in. You need access to the jQuery object because the official guidelines for jQuery development suggest returning the jQuery object to support chainability in your jQuery plug-in. (If you are unfamiliar with chainability, I’ll touch on the concept later in the section “Caching Selectors or Chaining.”) The following code shows an example of using the this keyword in a plug-in.

(function($) {
   $.fn.myPlugin = function() {
      //this refers to the jQuery object that was a result of the jQuery selection
      console.log("this.attr('id') = '" + this.attr('id') + "'");
      this.each(function() {
         //this refers to a DOM element that is part of the jQuery selection
         console.log(" = '" + + "'");
      return this;

Instead of using the previous code, you might more frequently encounter a technique that returns the each function immediately instead of returning  on a subsequent line. Take a look at the following:

(function($) {
   $.fn.myPlugin = function() {
      //this refers to the jQuery object that was a result of the jQuery selection
      console.log("this.attr('id') = '" + this.attr('id') + "'");
      return this.each(function() {
         //this refers to a DOM element that is part of the jQuery selection
         console.log(" = '" + + "'");

Here’s another scenario in which the this keyword can point to something other than the DOM element or jQuery object. In jQuery 1.4.2, a new method was introduced called proxy. This method allows you to define what the this keyword refers to inside an event handler.

The following code shows the creation of an object literal, including a userNameof “elijahmanor” and a tweet method that alerts the userNameoff of the thiskeyword.

As you might expect, if I call twitter.tweet(), you’ll see an alert displaying “Hello elijahmanor”.

//Object Literal
var twitter = {
   userName: "elijahmanor",
   tweet: function() { 
      alert("Hello " + this.userName); 

// Call tweet() method off of twitter Object Literal 
twitter.tweet(); // alert’s “Hello elijahmanor”

However, the result is different if you pass a twitter.tweet as the event handler parameter to one of jQuery’s event helpers or to the bind or live method. Instead of seeing “Hello elijahmanor”, as you might expect, you see “Hello undefined”. This happens because the this keyword references the DOM element that was clicked rather than the twitter object literal.

To change the functionality to show the alert “Hello elijahmanor” instead, you can use the new proxy jQuery method. Instead of passing twitter.tweet directly into the click argument, you can now wrap it inside the $.proxy() method. The first parameter of $.proxy() is the event handler function (in our cast, that is twitter.tweet), and the second parameter is the context that you want the this keyword to reference, which is the twitter object literal.

You can also use an alternate syntax in which the first parameter is the context (which is the twitter object literal) and the second parameter is a string representing the method that you want to represent the event handler off of the context, in our case “tweet”.

//Object Literal
var twitter = {
   userName: "elijahmanor",
   tweet: function() { 
      alert("Hello " + this.userName); 

/* Option #1: jQuery.proxy( function, context ) */
$("#update2").click( $.proxy( twitter.tweet, twitter ) );

/* Option #2: jQuery.proxy( context, name ) */
$("#update3").click( $.proxy( twitter, "tweet" ) );

2. Am I Referencing the jQuery Object or a DOM Element?

Even when you have a basic understanding of when the this keyword points to a DOM element or to a jQuery object, the concept can still be confusing once you save the value of this to a variable. Imagine that you are working in a complex function and you don't know whether your variable refers to a DOM element or a jQuery object. A common way to get around this confusion is to use a naming convention to help out. Here’s an example:

$('a').click(function() {
   var $anchor = $(this);

As you can see in the example, I wrapped the DOM element from the callback function with a jQuery object and then stored the results in a variable whose name is prepended with a dollar sign ($). The $ symbol doesn't have any special behavior, it is just a reminder to the reader that the variable refers to a jQuery object rather than to a DOM element.

There also might be occasions when you need the DOM element from a jQuery object. The following code snippets show several ways of obtaining the raw DOM element:

//Gets the collection of anchor tags from the jQuery array

//Various ways to get the 0th item in the jQuery array of DOM elements
$('a').get()[0]; //Get method returning jQuery array and then indexing 0th item
$('a').get(0); //Get method accessing DOM element at 0th index
$('a')[0]; //Array accessor syntax getting the 0th indexed item

If you have not used a naming convention and you aren't sure whether you are dealing with a jQuery object or a DOM element, you can use the following code snippet:

//Check if source is a jQuery object and contains one or more elements
if (source instanceof jQuery && source.length > 0) {
   var element = source[0];

3. Understanding Selectors

Most likely, you are familiar with the basic CSS selectors that jQuery provides, but unless you've done some digging, you might not be aware of some of the more advanced selectors. I’ll start off by describing ones you are aware of, and then we’ll branch out. In addition to the actual selectors, I’ll touch on some other concerns you should be aware of.

Simple Selectors

Here are examples of simple selectors:

//Selects all the anchor tags in the DOM

//Selects all the anchor tags inside of div elements in the DOM
$('div a')

//Selects all the elements with a class of 'odd'

//Selects all the tr elements with a class of 'odd'

Uncommon Selectors

Although jQuery supports CSS3 selectors, many Web developers are seemingly unaware of these features, primarily because of the lack of CSS3 browser support, which understandably leads many developers to not use CSS3 selectors when they build their style sheets.

Thankfully, jQuery has taken care of many cross-browser issues, and developers have made huge efforts to make their code work across a wide array of browsers, versions, and operating systems.

Here are some powerful CSS3 type selectors that you can comfortably use in your jQuery programs.

<!-- Selects all links that ends with mp3 in the href -->

<!-- Selects all links that are set to open a new window --> 

<!-- Selects all links that have a class that begins with "custom" -->

Advanced Selectors

In addition to the CSS3 selectors, jQuery has added more functionality to increase its flexibility in getting whatever element you are trying to select. Here are some examples:

<!-- Selects all the input elements (text, password, radio, etc...) -->

<!-- Selects all the disabled input elements -->

<!-- Selects the 4rd (0 based) list item -->

$('li > a[href$=pdf]')
<!-- Selects links to pdf files that are children of a list item-->

<!-- Selects list items that have links inside of them -->

Selector Context

Sometimes you want to select a set of DOM elements that are only from a particular area of your DOM. At first thought, you might try doing something like this:

$('span a.myClass').addClass('highlight');

Instead of searching through the whole DOM looking for your class, you can instead use an overloaded jQuery function and pass in the context where you want the selection to begin. This way, you are telling jQuery where to start, which can dramatically speed up the selection process. Here’s code that demonstrates this approach:

$('span a.myClass', '#myDiv').addClass('highlight');
<!-- Start at #myDiv context & use "span a" selector to find the link -->

Caching Selectors or Chaining

Seeing that jQuery selection is at the heart of most jQuery code, you should take notice of what your performance is like. A common technique to help with performance is to cache your selections if you plan to use them again later in your code.

The following shows an example of what an uncached code snippet might look like:

$('#myButton').click(function() {
   $('#alertMessage').html('<strong>Really Bad Error</strong>');

This example selects the alertMessage element on three separate occasions to perform simple operations. The performance hit of this code is minimal because it is only selecting three elements by their ID, but imagine if you were trying to select elements using a complex selector, such as $('li > a[href$=pdf]'), and you were performing operations inside a loop 100 times. I think you get my point. So, let’s rewrite the preceding code, but this time cache our selection:

$('#myButton').click(function() {
   var $alertMessage = $('#alertMessage');
   $alertMessage.html('<strong>Really Bad Error</strong>');

The only difference is that I introduced a new variable and saved the jQuery object from the selector's results.

Instead of caching as shown in the previous example, you can chain your actions together since each function returns the referring jQuery object. Let's change the previous code snippet to use chaining:

$('#myButton').click(function() {
      .html('<strong>Really Bad Error</strong>')

As you can see, you don’t need to store the results of the selector because you can just chain off the jQuery object returned from one function to another. The result is faster, cleaner code that is easier to read.

Useful Selector Playgrounds and Tools

Let's face it, developers love to get their hands dirty and just play around with their technology.

  • Karl Swedberg and Cody Lindley put together a great resource for playing around with jQuery Selectors. I highly recommend checking it out and building some of your own complex selectors against the sample DOM they provide.
  • If you aren't already using the Firebug Plug-in for Firefox, or you haven't fully exercised its features, I think doing so is definitely worth your time. I regularly use the console window to run jQuery against Web pages to consolidate, scrape,  manipulate content, or just test new ideas or techniques.
  • Note: If the Web site you are on doesn't already have jQuery loaded, you can use Karl Swedberg's jQuerify Bookmarklet to dynamically inject jQuery into the page so that you can play around. You can also use the FireQuery Plug-in for Firebug, which showcases the jQuerify function as well as providing many other handy features, such as visualizing data and event handlers attached to DOM elements in the HTML tab.
  • Whether you are getting starting with selectors or are an experienced jQuery developer, it is always nice to have a tool to make your job quicker, faster, and easier.
  • The SelectorGadget Bookmarklet, created by Andrew Cantino and Kyle Maxwell, allows you to interactively select elements from the DOM to obtain the selector you want. You start by selecting one or more of the items you are interested in and then you progressively select or unselect other items to obtain the selector right for your needs.
  • As long as you have Firebug, which I highly recommend, you can also use Robert Nyman's FireFinder plug-in to assist your jQuery selection process. Not only does it have many of the features of SelectorGadget, but since it's a Firebug add-on, you can also inspect the elements. Also, a little feature that sets it apart is that it has a FriendlyFire feature that integrates with JsBin to easily share snippets of code with others.

Note: You can watch an informative video by David Ward, entitled See how I used Firebug to learn jQuery, in which he highlights using Firebug and the SelectorGadget Bookmarklet mentioned earlier.

4. Combine and Minify Your Scripts

The great thing about jQuery is that so many jQuery plug-ins are available and many new ones are created daily. What I have noticed is that there are so many good plug-ins, that I end up having 10 or more plug-ins referenced on my Web site at one time. If you know anything about performance, you know that this is a problem on several fronts.

Section 8.1.4 of the HTTP/1.1 RFC recommends that a "single-user client SHOULD NOT maintain more than 2 connections with any server or proxy." But what does that mean? Well, it recommends that a Web browser should only download up to two resources at one time from one domain. This can become a very large problem if you have numerous resources (such as 10 or more jQuery plug-ins, as mentioned above).

The good news is that most modern browsers don't follow the letter of the HTTP/1.1 RFC law, and many can utilize either four or six concurrent connections while downloading resources for your Web site. For more information about these concurrent nuances, you can refer to an in-depth article by Steve Sounder's, entitled Roundup on Parallel Connections

Another piece of bad news is that when a script is being downloaded, it blocks all other parallel downloads from starting until the script download is done. This occurs because the script files might manipulate code, include other files, or change the rendering process, so the browser waits for the script to finish.

All that to say that you should minimize your scripts to be as small as possible and then combine them so that only one connection is necessary to download the script to your client's browser.

Leaving your scripts uncompressed and separate during the development process is fine because you might find an issue with one or more of them, and debugging them in their original state is much easier. However, once you start to deploy your scripts into a QA or production environment, you should consider minifying and combining your scripts.

Many great tools are out there to accomplish this goal. I recommend using either Microsoft AJAX Minifier or Yahoo!'s YUI Compressor to minify your code. Both of these tools have their pros and cons. For an in-depth review comparing these tools, take a look at Ajaxian's Microsoft Ajax Minifier VS YUI Compressor.

Note: For .NET developers, myself included, there is an open source project called YUI Compressor for .NET, which is a .NET port of the original Java project and provides a nice MSBuild task to integrate with your build process. Many thanks to Karl Seguin and the other developers who made this open source project available.

Some good resources with information about these concepts and other performance issues are Yahoo!'s Best Practices for Speeding Up Your Web Site.

In conjunction with these good resources, Yahoo and Google have made Firefox Firebug plug-ins to enforce these rules. If you haven't already, you should install Yahoo!'s YSlow and Google's Page Speed.

5. Different Ways of Storing Data

 In this section, I’ll cover different ways of storing data.

Don't Use Attributes

Before the days of jQuery, a common practice was to store additional data in your DOM by adding custom attributes to your elements. You might see developers creating their own attributes or reusing less used attributes such as alt or title. This approach has several problems. If you create your own attributes, your code is not XHTML compliant, and if you reuse an attribute, you’re using one that really isn't intended for that purpose. Here’s an example:

//Storing special information about the anchor in the alt attribute
$('a').attr('alt', 'Special info about this HTML tag');

//Getting the special information from the anchor's alt attribute

Utilizing the jQuery data Function

A much better way to store information for a particular HTML element is to use the jQuery data function, shown here:

$('a').data('specialInfo', 'Special info about this HTML tag');


Not only are you not reusing an attribute that wasn't intended to hold additional information, but you are also able to name the key without jeopardizing XHTML compliance. Another great feature of the data function is that it doesn’t limit you to string data, which you are when you store data inside an attribute. You can store complex data structures inside the data function and then retrieve them again. You should note that by using this approach, you can't store data directly in the HTML element at design time. Here’s an example of storing a complex data structure:

//Storing a complex data structure under the specialInfo key
$('a').data('specialInfo', {
   firstName: 'Elijah',
   lastName: 'Manor'
//Getting the complex data structure specialInfo & accessing the firstName property

Actually, you can use a different syntax to store and retrieve information using the datamethod that is faster than using the key/value approach. Here's an example:

$("li.demo").data({ firstName: "Elijah", lastName: "Manor" });


    { firstName: "Andrea", lastName: "Manor" });



If you want, you can use both syntaxes at the same time. As the preceding example shows, you can attach an object literal directly to the data method and then add more data using the key/value syntax. Both pieces of information will be attached to the DOM element. When retrieved by using the data method, the result will look something like the following screen shot, which shows the output from the preceding code. Notice that you can reference the key you attached previously with a string and use that as a property name off of the result from data.

Figure 1

Use the Metadata Plug-in

Using the Metadata plug-in is another interesting way to store information inside an HTML element. This approach is XHTML compliant and does not compromise the integrity of your attributes. The Metadata plug-in works nicely when you are developing your own custom plug-in, but it can also be useful for normal jQuery development.

A common way to use the Metadata plug-in is to provide additional JSON information inside your class attribute. The metadata that you add to the element is then used to override any setting that you might have already set at that point.

Let's assume that we have a tooltip jQuery plug-in that supports the Metadata plug-in and that our plug-in takes color, fontSize, and isAnimated as its settings. Since the tooltip plug-in supports the Metadata plug-in, we can selectively override the global settings for individual elements, as shown here:

<script type="text/javascript">
   $(function() {
         color: 'black', 
         fontSize: '14px', 
         isAnimated: false

<a href="" title="Yahoo Rocks!">Yahoo</a> 
<!-- Yahoo Rocks! will use the default settings of black, fontSize 14px, and isAnimated false -->

<a href="" class="{color: 'red'}" 
   title='Google Rocks!'>Google</a> 
<!-- Google Rocks! will be red, fontSize 14px, and isAnimated false -->

<a href="" 
   class="{color: 'blue', fontSize: '22px', isAnimated: true}" 
   title="Microsoft Rocks!">Microsoft</a> 
<!-- Microsoft Rocks! will be blue, fontSize 22px, and isAnimated true-->

And here is a skeleton of what the tooltip jQuery plug-in might look like to support the previous implementation.

(function($) {
   $.fn.tooltip = function(settings) {
      return this.each(function() {
         var $element = $(this);
         var elementSettings = $.metadata ? 
            $.extend({}, settings, $element.metadata()) : 
         //Use the elementSettings here...

Without getting too deep into the details of how to write a jQuery plug-in, the preceding code loops through the elements that were selected and combines the metadata (if the Metadata plug-in is defined) from the element with whatever settings were passed into the tooltip plug-in.

You can find more features and uses of the Metadata plug-in from the Metadata Plug-in Page hosted on jQuery's Web site.

6. The Dos And Don'ts of Events

To conclude, let’s look at some of the dos and don’ts of working with events in jQuery.

Preventing Default Behavior

You won’t work with jQuery for very long before you run into a situation where you need to prevent an event from completing. For example, you have registered the click event for an anchor tag, but you don't really want the page to navigate away to another location.

You can actually accomplish this in two different ways. One approach is to return false from your function, as shown here:

$('a').click(function() {
   return false;

The other approach is to call the preventDefault function off the event that is passed into the callback function. An advantage of using this function is that you can use another function, called isDefaultPrevented, later in the function if you need to know whether someone called preventDefault.

$('a').click(function(e) {

So which approach should you use? There are some subtleties in these approaches that you should consider. The return false approach essentially executes e.preventDefault and e.stopPropagation behind the scenes, whereas e.preventDefault allows the event to continue and propagate to any other event handlers. The decision about which approach to use really depends on what behavior you are looking for. I personally tend to use e.preventDefault because it is verbose, and I think it is easier understood by whoever is reading the code.

Back to School Binding

There are a lot of event helpers that jQuery provides, such as blur, change, click, focus, keydown, and mousedown to name a few.

From my experience, most developers use the jQuery event helpers to wire up their event handlers. This isn't a bad practice, but I think sometimes the power and simplicity of the basic bind function is forgotten.

For example, if you want to attach the same event handler to multiple events using the helpers, you would have to wire up some code like this:

var clickMe = function() {
    console.log('Hello World!');


If you use the bind function instead, you can do the same thing but in a much simpler fashion, as shown here:

var clickMe = function() {
    console.log('Hello World!');

$("p.clickMe").bind("click dblclick", clickMe);

$("p.clickMe").unbind(); //really dangerous
$("p.clickMe").unbind("click dblclick"); //moderately dangerous
$("p.clickMe").unbind("click dblclick", clickMe); //safe

You can also remove the binding by calling the unbind method. As the preceding code snippet indicates, three different approaches are available for removing event handlers. The first is to callunbind, but this approach is really dangerous because it removes all event handlers for all events for the jQuery selection. Doing so could cause unexpected behavior if event handlers were attached by another application. The second syntax is to specify the events for which you want to remove event handlers. Again, this is a dangerous approach because you aren’t specifying specific event handlers. You very well could remove event handlers that you shouldn’t be unbinding. The last syntax is the safest. Here, you provide the event handler that you want remove to a defined list of events.

Note: Another huge benefit of using the bind function instead of the helpers is that you can create and trigger your own custom events.

Live and Let Die

Version 1.3 of jQuery introduced the concept of live events. Instead of using the bind function to register your events,  you can use the live function instead. The bind function registers the event handlers with the actual DOM elements that were selected,  but the live function registers the event handlers on the document.

What does this buy you? The benefit of the live function is that since the event handler is registered on the document, it enables the automatic registering of any subsequently created elements matching your selector to also fire the event handler you defined.

Here’s what this looks like from a real-life practical perspective.

$("p.sayHello").bind('click', function() {
   console.log('Hello World!');
$('body').append("<p class='sayHello'>Dynamic Say Hello</p>");
<!-- When clicked, "Dynamic Say Hello" will not print "Hello World!" to the console because it was created dynamically after the event handler was attached to the selected elements -->

Let's change the code snippet just slightly by using the live function instead of bind:

$("p.sayHello").live('click', function() {
   console.log('Hello World!');
/* die() || die("click") || die("click", clickMe) */
$('body').append("<p class='sayHello'>Dynamic Say Hello</p>");
<!-- When clicked, "Dynamic Say Hello" will print "Hello World!" to the console because it used the live method instead of the bind method -->

I added as a comment the syntax to remove the event handler attached by the live method. As before, there are three ways to call the die method, ranging from dangerous to safe.

You’ll be glad to know that since jQuery 1.4, all the events for live are now supported. Previously, in jQuery 1.3.2 and earlier, the following events were not supported: blur, focus, mouseenter, mouseleave, change, and submit. As of jQuery 1.4, these events are now fully supported and are viable options for your project.

In the same fashion as the live and bind methods, jQuery 1.4.2 has introduced two new methods, called delegate and undelegate. These methods behave the same way, but instead of the document being the root node that events bubble up to, you can know define your own custom root node, which can considerably increase the performance of your event bindings because your events don’t have to bubble all the way up to the document. Here’s an example of how you would use this new syntax:

var clickMe = function() {
    var element = $(this);
    element.text(element.text() + ' :)');

$("ul.demo").delegate("li", "click", clickMe);
/* undelegate(), undelegate("li", "click"),
    undelegate("li", "click", clickMe) */

$("ul.demo").append("<li>Dynamic Item</li>");

This code creates a delegate off of the unordered list (ul) and is listening to the click event off of the list item (li) children. When a list item is clicked, the event propagates up to the unordered list, and at that point the event handler is called, appending a new Dynamic Item list (<li>Dynamic  Item</li>) item to the unordered list.

I added as a comment the syntax to remove the event handler attached by the delegate method. As before, there are three ways to call the undelegate method, ranging from dangerous to safe.


jQuery is a great JavaScript library that is fast, easy to use, and powerful. I find that it is a fairly easy library to start using immediately, and once you start using it more and more, you will find yourself needing to understand some of the deeper concepts to get the full benefits of the library.

I hope that this article has made you aware of some of these important concepts. In addition, there are other things that you should familiarize yourself with, such as how to create a jQuery plug-in, how to use jQuery alongside other JavaScript frameworks, how to perform complex animations, best practices using AJAX, and so on.

The jQuery community  has grown quickly, and the number of plug-ins, tutorials, articles, and Web sites increase every day. If you are interested in continuing your jQuery learning, I encourage you to follow me on Twitter for a fresh set of jQuery links and to check out my blog for my daily Tech Tweets roundup blog posts that contains numerous jQuery links to aid in your learning process.


About the Author

Elijah Manor is a Christian and a family man. He develops at appendTo as a Senior Architect providing corporate jQuery support, training, and consulting. He is an ASP.NET  MVP, ASPInsider, and specializes in ASP.NET MVC and jQuery development. He enjoys blogging about the things he learns. He is also active on Twitter and provides daily up-to-date Tech Tweets.

Find Elijah on: