I was asked very recently what happens to a bunch of dynamically added <li> items if you attached a click event to the ones that were there before. Will they automatically have the click event attached too? Or they won’t react to clicks?

$('li.classname').on('click', function() {
    // Do something in here
});

This is a common problem web developers had about 3 years ago, and I am surprised people still don’t get it.

The answer is easy, no, they won’t get the click event unless you do one of two things:

  1. Reattach the events in a callback after your dynamic operation is complete and the new DOM is ready.
    1. If you expect your DOM to change, attach the click events using event delegation and forget about it.

My personal preference is number 2 of course. The first might be your only option if there is no easy way to do the delegation, or the ancestor element contains more elements that might make it hard to create a selector for the children.

Event Delegation with jQuery

There is a very good explanation about what delegation is, means, and why do you need to know about it, right [here](http://learn.jquery.com/events/event-delegation/ “here”). Check the examples in that page from the jQuery documentation.

The basic definition jQuery gives in that link: Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.

Yes, the key here is the “… added in the future” part. Back in jQuery 1.5 (I believe) we had the .live() method to do this for us, but it was both deprecated and removed in later versions, it was a very slow and crappy solution for a problem that started appearing with the advent of AJAX and its dynamic DOM manipulation. The guys at jQuery realized there are better ways to do this, and came up with a smarter solution, event delegation.

What you do is attach the click (or any other) event to a parent container element instead, then specify which child elements should trigger it. HTML will bubble up these events all the way to the root of the DOM unless they are handled on the way up, so the click on the child element will bubble up to its parent and our .on(‘click’) handler will kick in, check if the sender is one of the specified elements and handle the click appropriately.

$('ul.containerclass').on('click','li',function() {
    // This click will only be triggered if it comes from one of the children &lt;li&gt; elements
});

This way you don’t have to worry about AJAX calls modifying the contents of the container and adding/removing elements. No extra .on(‘click’) attachments in your callbacks, just the original one in $document.ready will take care of it.

As always, [I’ve prepared a plunk to demonstrate](http://plnkr.co/0VUAtjT6suuG14CyG6TL “I’ve prepared a plunk to demonstrate”).