Live Events

The bind() method binds event handlers to specific document elements, just as addEventListener() and attachEvent() do. But web applications that use jQuery often dynamically create new elements. If we’ve used bind() to bind an event handler to all <a> elements in the document, and then we create new document content with new <a> elements, those new elements will not have the same event handlers as the old ones, so they will behave differently.

jQuery addresses this issue with “live events”. To use live events, use the delegate() and undelegate() methods instead of bind() and unbind(). delegate() is usually invoked on $(document) and is passed a jQuery selector string, a jQuery event type string, and a jQuery event handler function. It registers an internal handler on the document or window (or on whatever elements are in the jQuery object). When an event of the specified type bubbles up to this internal handler, it determines whether the target of the event (the element that the event occurred on) matches the selector string. If so, it invokes the specified handler function. So to handle “mouseover” events on both old and newly created <a> elements, you might register a handler like this:

$(document).delegate("a", "mouseover", linkHandler);

Or, you might use bind() in the static portions of your document and then use delegate() to handle the portions that change dynamically:

// Static event handlers for static links
$("a").bind("mouseover", linkHandler);
// Live event handlers for dynamic parts of the document
$(".dynamic").delegate("a", "mouseover", linkHandler);

Just as the bind() method has a three-argument version that allows you to specify the value of the data property of the event object, the delegate() method has a four-argument version that allows the same thing. To use this version, pass the data value as the third argument and the handler function as the fourth.

It is important to understand that live events depend on event bubbling. By the time an event bubbles up to the document object, it may have already been passed to a number of static event handlers. And if any of those handlers called the cancelBubble() method of the Event object, the live event handler will never be invoked.

jQuery defines a method named live() that can also be used to register live events. live() is a little harder to understand than delegate(), but it has the same two- or three-argument signature as bind() and is more commonly used. The two calls to delegate() shown above could also be written using live():

$("a").live("mouseover", linkHandler);
$("a", $(".dynamic")).live("mouseover", linkHandler);

When the live() method is invoked on a jQuery object, the elements in that object are not actually used. What matters instead is the selector string and the context object (the first and second arguments to $()) that were used to create the jQuery object. jQuery objects make these values available through their context and selector properties (see Queries and Query Results). Normally, you invoke $() with only one argument and the context is the current document. So for a jQuery object x, the following two lines of code do the same thing:

x.live(type,handler);
$(x.context).delegate(x.selector, type, handler);

To deregister live event handlers, use die() or undelegate(). die() can be invoked with one or two arguments. With one event type argument, it removes all live event handlers that match the selector and the event type. And with an event type and handler function argument, it removes only the one specified handler. Some examples:

// Remove all live handlers for mouseover on <a> tags
$('a').die('mouseover');  
// Remove just one specific live handler
$('a').die('mouseover', linkHandler); 

undelegate() is like die() but more explicitly separates the context (the elements on which the internal event handlers are registered) and the selector string. The calls to die() above could instead be written like this:

// Remove all live handlers for <a> tags
$(document).undelegate('a'); 
// Remove all live mouseover handlers for <a> tags
$(document).undelegate('a', 'mouseover'); 
// Remove one live mouseover handler for <a> tags
$(document).undelegate('a', 'mouseover', linkHandler);

Finally, undelegate() can also be called with no arguments at all. In this case, it deregisters all live event handlers that are delegated from the selected elements.

Get jQuery Pocket Reference now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.