You are free to browse all of the content on this site, however if you want to post comments or replies you will need to register for a free account. Becoming a registered member also disables some of the more annoying ads whilst you are logged in.

jQuery: Event Binding Tutorial

jQuery is a powerful library that makes difficult things easy; sometimes that ease of use comes with a learning curve. Event handling is one of those curves.

Raw Javascript Event Handling

If you've done much programming with javascript you're familiar with event handling. In its most rudimentary form, it looks like this:

HTML Code:

<a href="#" onclick="alert('Ouch!')">Click Softly</a>

In an HTML document, the previous line would put up an alert box when the link is clicked. This gets a little messy if you attach event handlers to many items. The normal solution is to attach events via javascript, keeping the functionality separate from your HTML. Here's how we might rewrite that:

However, binding events in this way has some problems. While all modern browsers accept it, you can only define one function per event. If you want an item to handle multiple tasks per click, you'd have to call those functions in the click handler function. It can very quickly become a maintenance disaster.

Registering Multiple Events Handlers

If you want multiple events handlers, you have to use the more modern event registration model. Internet Explorer's event registration is different then all the other major browsers. Also IE doesn't handle the 'this' keyword within triggered functions the same way other browsers following the W3C model do.

jQuery takes these differences and abstracts them away, leaving a single model for all supported browsers. Attaching an event looks very similar to the basic event attaching method I described earlier. Here's an example:

Code:

$('#X').click(function() { alert('Ouch!'); }

This code will work in all modern and many not-so-modern browsers. It allows multiple events and gives you access to the 'this' keyword. It's event handling nirvana. So what's to learn?

jQuery Event Handlers - $.bind()

There are three basic event handler methods in jQuery: $.bind(), $.live(), and $.delegate - each works differently. To get the most out of them you need to understand what they do.

$.bind is the basic workhorse of event handlers, along with its many shortcuts. The example in the previous section using $.click is actually a shortcut for $.bind. The same line could be rewritten like this:

Code:

$('#X').bind('click', function() { alert('Ouch'); }

$.bind is also flexible in that it allows you to bind multiple events at once. This is done by passing an object of handler/function pairs. Here's an example:

These multiple events/multiple handler models cannot be accomplished with shortcut methods -- ie. .click(); those are designed for the simple one function to one event model.

Event Object & Default Actions

If link #X had a target - say another page, and you clicked it, it would still take you to that page. In many cases when binding events you don't want that to happen. You want the default action to be replaced by your programmed action. To do this we use the event object. The event object is passed into your event handler function by default. To make use of it, you can provide for it in the function call.

Code:

$('#X').bind('click', function(event) { .. do stuff .. });

The most basic use of the event object is to stop the default behavior with the .preventDefault method.

This can be used to prevent a form submission or a link from firing. It's possible that you'll never need a type of event binding other then .bind - but it's unlikely. Why? Here's an example of what $.bind won't do.

If you click the original link, it will add more links to the page. But if you click on subsequent, created links, they won't do anything, even though they share the same class. Why? Because $.bind only binds events to elements that exist at the time it's called.

jQuery Event Handlers - $.live()

Enter $.live() - live binds events to all current and future elements that match the selector. How does it do this? No, it's not psychic.

When you pass an event handler to .live() it doesn't attach the event to the element - it attaches it to the root node of the document.

When an event occurs it bubbles up the document tree, eventually reaching this root node. When it gets there, it's handled by the code set up by live. This is how it can handle elements that don't exist when the binding is created.

$.live() has some shortcomings. You can't use live in a method chain - very un-jQuery like.

Live also has some minor performance issues to be aware of; the event has to bubble to the root node to be acted on, which takes (minor) time. Also if something along the way gets the event and stops propagation, the live handler will never fire.

A new addition to jQuery is $.delegate, which is meant to be a replacement for $.live().

jQuery Event Handlers - $.delegate()

Internally, jQuery uses $.live to implement $.delegate, but $.delegate has a better API and in most cases will be the better choice if you want handlers that attach to all current and future elements.

The basic syntax for $.delegate takes three parameters: the element to which you wish the event to be attached, the event type, and the function.

What happens here? Delegate is creating an event handler and attaching it to all table tags. That's the context. This event handler listens for td tags within table tags (is there another kind?) receiving click events.

Using a context allows the handler to be closer to the originating event, but allows future elements to still be bound. If you wanted functionality akin to $.live you could give the document body as the context.

Code:

$('body').delegate('.link', 'click', function(event) { ...

Delegate can also be used in method chaining, unlike $.live.

Code:

$('body').find('div').delegate('.link', …

And you can use literal DOM elements

Code:

$(document.body).delegate('.link', ...

In the second example the context is the div element, rather then the body. This event will not fire for .link elements not contained in div element. It's this preciseness and flexibility that make $.delegate a much better option then $.live.

Remember to wrap your event bindings in a $(document).ready block -- you can't bind events if there's no DOM to bind them to!

Conclusion

Binding javascript functions to DOM events - click, hover, mouseover, etc - is what allows you to add interactivity to your site. Once you've learned this first building block, you're ready to start enhancing web pages with jQuery and javascript.

In our next jQuery article, we're going to use $.bind and learn how to create a basic plug-in -- its a pattern you'll use over and over to make your jQuery code easy to reuse!