The Dos And Don'ts of Events
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) { e.preventDefault(); });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!'); }; $("p.clickMe").click(clickMe).dblclick(clickMe);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); //safeYou 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.
We would love to hear from you...