When you first start learning jQuery, we learn to add events like this.
Notice how the event for
.add-input is inside
document.ready(). This means that once the document is ready we will attach a event click listener to
This code works fine in most cases, but what happens if an element is added after
Dynamic Form (Naive Example)
Let’s take a simple example of making a dynamic form. Say we’re making an app and we want to add inputs to our form.
In the example below we have the basic form example from before, with and extra button. When the new “+” button is clicked it will append an input to the form creating a form with multiple inputs. However, the problem is the newly generated input buttons don’t work the same way as the first button.
Try clicking the “Add Input” button of a newly generated input, in the Codepen above.
Here’s where things get tricky.
This code above says add a click event listener to the
add-input class. However since the new elements are added after the
$(document).ready() the events for
$('.add-input').click() never get called again after the first
Dynamic Form (Callback Example)
To fix problem we must attach our event listeners in the callback when we click the “+” button. So now every single time an input gets added it will also add
click() event to it as well. Unfortunately this comes with it’s own problems.
Since we’re adding an event for every input we add, we are also re-adding the event listeners for every button resulting in multiple events.
To stop this we must add
$(".add-input").unbind( "click" );. This allows us to remove all previous events that were attached. This leaves us with a single click event for each input button.
Our code for what should be a simple dynamic form has grown into a mess. It is complex to say the least with all of the adding and removing of events. Imagine if we had a much more complex form, the code would leave us in callback hell. Luckily there is a better way.
Dynamic Form ($(document).on Example)
As of jQuery 1.7, we now have the
on() is nifty, because it keeps track of the document even as we dynamically add inputs. With
on() there is no need for adding complex callback code. We don’t need to remove events only to add them back right after.
We get the same result, but the resulting code is so much cleaner. No matter how many inputs we add, the code works without any problems.
$(document).ready() is a great function to call when things the DOM is ready, but beginners can’t rely on it for everything.
$(document).on() is fantastic for adding event listeners, because it listens for any selector added on the document no matter when it is added.