Prasenjit Kumar Nag a.k.a Joy

A Developers Adventure in Coding

On and Off jQuery’s New Event Binding Awesomeness

I have been using jQuery for quite a while and have used all of jQuery’s event handlers like $.bind $.live $delegate $.click etc. 

Along with the release of jQuery 1.7 , jQuery introduced two new methods for event handling. They are $.on and $.off and in jQuery.com they encouraged use of these two methods for event binding. Because no mater what other method you use like $bind , $live, $delegate jQuery is using $.on for all these under the hood. For a proof of these lets take a look at $bind , $live, $delegate definition in jQuery’s source.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
bind: function( types, data, fn ) {

return this.on( types, null, data, fn );

}

unbind: function( types, fn ) {

return this.off( types, null, fn );

}

live: function( types, data, fn ) {

jQuery( this.context ).on( types, this.selector, data, fn );

return this;

},

die: function( types, fn ) {

jQuery( this.context ).off( types, this.selector || "**", fn );

return this;

}

delegate: function( selector, types, data, fn ) {

return this.on( types, selector, data, fn );

}

undelegate: function( selector, types, fn ) {

// ( namespace ) or ( selector, types [, fn] )

return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );

}

Now you can see that jQuery itself is using $.on and $.off for all event handling. So it’s good time to start using these new functions for event handling.

Let’s take a look at the syntax of $.on  and how we can use it as a replacement for $.live, $bind and $delegate. Here is the function definition for $.on from jQuery.com.

.on( events [, selector] [, data], handler(eventObject) )

events One or more space-separated event types and optional namespaces, such as “click” or “keydown.myPlugin”. selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. data Data to be passed to the handler in event.data when an event is triggered. handler(eventObject) A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false

seeing all these arguments it may seems a bit scary at first glance but you dont need to remember all of this. You just need to remember two basic scenarios we need most of the time.

If you need a simple event binding which doesn’t need to persist to elements dynamically added to DOM(Document Object Model) through ajax or jQuery codes then you can use on directly on the target element using the syntax

1
2
3
4
5
6
7
8
9
$(selector).on(event,handler);

//example

$('a.simple').on('click',function(){

alert('I was clicked');

});

This will be added to all anchor elements with a class of simple. But if you add new elements after the DOM is loaded this event binding wont work.

Now if you want the event binding persist to new elements added to the dom then the syntax is a bit different

1
2
3
$(document).on('click','a.complex',function(){
alert('I was clicked');
});

now I am attaching the click event to document instead of the target element. Why is that? Because I want the event binding works for new elements too.

So what will happen when user click on an element?

If you have idea about event bubbles in JS then you know that any events triggering travels from source element to its parents unless you specify other wise.

So when user will click on any element document object will get a click event and on method will check if the source of the event is ‘a.complex’ if it’s true then it will fire the handler function. Check this in the following fiddle

[jsfiddle url=“http://jsfiddle.net/GhbZv/6/” height=“400px” include=“result,html,js,css”]

Now as we are attaching the event with document as document will always exist in DOM it will work for all matching elements no matter when they are added to the DOM.

The syntax for $.off is simple

1
2
3
4
5
$(selector).off();

// to turn off a specific handler the syntax will be

$(selector).off(handler);

Though jQuery still supports previous event binding method’s, it’s good to write new event handlers using this two new methods, at least you can save a function call with this.  :)

Update:

And here goes some examples how you can convert previous $.bind, $.delegate or $.live calls

1
2
3
4
5
6
7
8
9
10
11
12
13
/* for $.bind to $.on */
/* Old: */ $(".foo").bind("click", handler);
/* New: */ $(".foo").on("click", handler);

/* for $.delegate to $.on */

/* Old: */ $("#container").delegate(".foo", "click", handler);
/* New: */ $("#container").on("click", ".foo", handler);

/* for $.live to $.on */

/* Old: */ $(".foo").live("click", handler);
/* New: */ $(document).on("click", ".foo", handler);

Comments