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:
<a href="#" onclick="alert('Ouch!')">Click Softly</a>
<a id="X">Click Softly</a> <script> document.getElementById('X').onclick = function() { alert('Ouch!'); } </script>
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:
$('#X').click(function() { alert('Ouch!'); }
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:
$('#X').bind('click', function() { alert('Ouch'); }
$('#X').bind({ click: function() { alert('Ouch!'); }, mouseover: function() { alert('Don\'t Click Me!'); } });
$('#X').bind('mouseenter mouseleave', function() { $(this).toggleClass('entered'); });
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.
$('#X').bind('click', function(event) { .. do stuff .. });
$('#X').bind('click', function(event) { event.preventDefault(); alert('I\'m not going anywhere.'); });
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.
$('.link').bind('click', function(event) { event.preventDefault(); $('body').append("<a class='link' href='#'>More!</a>"); });
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.
// This will NOT work $('.bindmme').find('div').live('click', function() { ... }); // Don't chain with live, and it's fine $('#myDiv').live('click', function() { ... });
// These examples fail, don't do them! $(document.body).live( ... $(this).live( ...
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.
$('table').delegate('td', 'click', function() { alert('No Clicking Tables!'); }
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.
$('body').delegate('.link', 'click', function(event) { ...
$('body').find('div').delegate('.link', …
$(document.body).delegate('.link', ...
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!
Message