6 January 2012

jQuery Event handler Attachments live, delegate, on

JQuery has powerful event handlers, from 1.0 jquery has a bind function to handle the events of the selectors.

For example
<script type = "text/javascript" >
 $('div.#help').bind('click', function () {
  alert('clicked the Help');
 });
</script>

Above click event is bind to the selector (i.e div element with ID 'Help'), so when a user clicked on the div element the event triggered and alert shown.

With new version new functions for the event handler is also introduced. From 1.3 live function is introduced, this function will attach event handler to document and calls the handler when event occurs on all elements that match the selectors. As with ajax, dynamic content can be added to the page at any time, the bind function will attach events handlers to only existing elements, for those elements added through the ajax, we need to call the bind function once again. This is repeating of same function calling. For this .live came to help, Live will attach event handler to the document and calls the event handler when the event occur on the selector, so the selector may exist or may added in future.

$(selector).live(events, data, handler); // jQuery 1.3+

As the event handler is attached to the document, the events bubble, or propagate, from the deepest, innermost element (the event target) in the document where they occur all the way up to the body and the document element. This is slowest one so in next version i.e 1.4 a new function .delegate is introduced.

.delgate function will attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements. here the improvement is the event handler is not attached to document but to the set of root elements.

$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+

Here is a example
$("table").delegate("td", "click", function() {
  $(this).toggleClass("chosen");
});

Above snippet attach a handler to click event to the selector "table", but calls the handler only when event occurs on "td", which is a selector passed as first argument, therefore td shall exist while this function executed or may be added to the table in future.

One important note from jQuery Documentation
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will propagate to the elements to which they are delegated; event handlers bound on any elements below it in the DOM tree will already have been executed by the time the delegated event handler is called. These handlers, therefore, may prevent the delegated handler from triggering by calling event.stopPropagation() or returning false.

Now in the latest version 1.7 .live and .delegate is replaced with .on which perform the action of the above said functions.

The syntax for the function
$(document).on(events, selector, data, handler); // jQuery 1.7+

If selector (the second argument) is not passed then the event handler attached the document and handler is called when the event occurs on the document(root element). If the selector is passed then the event handler called only event occur on the selector.

Here is a example
$("body").on("click", "p", function(){
      $(this).after("<p>Paragraph Clicked! </p>");
    });

Performance
The event like click are occur rarely, so it will not have a impact on performance. But event like mousemove will occur many time per second. so we must be carefull when we use the events like mousemove, we must cache, so that the calculation will not need to happen on every call.

jQuery can process simple selectors of the form tag#id.class very quickly when they are used to filter delegated events. So, "#myForm", "a.external", and "button" are all fast selectors. Delegated events that use more complex selectors, particularly hierarchical ones, can be several times slower--although they are still fast enough for most applications. Hierarchical selectors can often be avoided simply by attaching the handler to a more appropriate point in the document. For example, instead of $("body").on("click", "#commentForm .addNew", addComment) use $("#commentForm").on("click", ".addNew", addComment).

1 comment: