jQuery’s .bind(), .live(), .delegate() and .on()

Howdy! There!

It was a Saturday afternoon and I was relaxing + watching ‘Monk’ on my laptop. Suddenly from nowhere my wife jumped next to me and shouted ‘why the Helll! – anchor link doesn’t work, every time I update the section of a website?’. I was all confused and after pausing the show I politely replied her “Sweetheart – I don’t know.” I resumed the show after giving her response. She stood there silently giving me a look as if she was saying “we are not done! yet”

I paused the show again and thought to solve her problem in Monk’s way. I asked here three questions

  • when do you bind click event? her answer was “on document ready”
  • how are you updating the section? her answer was “via Ajax call”
  • and how did you bind the click event? she replied “by simple jquery click() method”

After putting all her answers together, I gave her a big smile (just as Monk do whenever he solves the case :)). She asked me why I am smiling. I told her to go and look for jQuery’s .on() and .delegate() method. Using either of them instead of bind() method will fix her problem. I also pointed her to Steve Schwartz wonderful blog post The difference between jQuery’s .bind(), .live() and .delegate()

And I decided to capture the key points of Steve’s blog post explaining the jQuery’s .bind(), .live() and .delegate() method. So first let’s look at the basic DOM tree and how the event bubbling works.

DOM Tree and Event bubbling

$('a').bind('click', function() {alert("Hello World!") });

When user clicks the anchor link – he causes the event handler bound to a ‘<a>’ tag to be fired first and after that the information is broadcasted to its parent element and there after all ancestors elements that one of their descendant element has been clicked. This propagation of event is called Event Bubbling. During this bubbling face, any ancestor element who has click handler bound to it will be executed. Now lets see how each of bind(), live() and delegate() works

.bind()

$('a').bind('click', function() {alert("Hello World!") });

.bind() is most basic way of attaching a click() event to any element in jQuery. $(‘a’) – scans the whole document for all the anchor tags and binds a alert function to each of their click events. The bind() method works only on elements which are present in the DOM when the script is being executed.

So taking the above example – if I inject an anchor tag via AJAX in the DOM after the script has already been executed, the new anchor tag will not have any click event bound to it. (BTW this is what was happening with my wife’s code). To make sure the event gets automatically bind to future elements (elements not present in DOM at a time), one should use the jQuery’s live() or delegate() method.

.live()

jQuery’s .live() has been deprecated as of version 1.7. Instead use jQuery’s .on() method


$('a').live('click', function(){alert("Hello World!")})

In case of .live(), the click event is bound to the $(document )(root node) along with event ‘click’ and ‘a’ – CSS selector as the parameters. Any time an event bubbles up to the document node , it checks to see whether the event was a ‘click’ and if the target element of event matches ‘a’ – CSS selector. If both are true, the event handler is executed.

The .live() method can also be bound to a specific element (or “context”) other than document, like this:

$('a', $("#container")).live('click', function(){alert("Hello World!")})

.delegate()

$("#container").delegate('a','click', function(){alert("Hello World!")})

The .delegate() method works similar to live(), except that it binds event to the supplied CSS selector. In above example jQuery scans for $(“#container”) and binds the alert function along with the click event and ‘a’ CSS selector as the parameters.

Now anytime a event bubbles up to $(“#container”), it checks to see if the event was a click and if the target element of the event matches ‘a’ CSS selector. If both are true, event handler is executed

.on()

$("#container").on('click', 'a', function(){alert("Hello World!")} )

The .on() event handler is designed to replace both the .bind() and .delegate() event handlers. It work exactly same as the .delegate() but with a minor syntax change. In .on() method the eventType comes first and CSS selector second as oppose to CSS selector first and event type second in .delegate() method.

The jQuery .bind(), .live(), and .delegate() methods are just one line pass through to the new jQuery 1.7 .on() method

Related Reading