Adding events to ajax appended content

ajax, javascript, jquery

Solution

You can bind the $.on to a parent element that will always exist in dom like this.

$(document).on('click','.test', function() {
            console.log('Test clicked');
        });

Note that: You can replace `document` with any parent of the element that will always exist in dom, and the closer the parent the better.

Simple event binding with `click` wont work as `click` bind the event handlers to elements that already exists in dom at the time of binding. And hence it doesn't work for elements dynamically added to dom later through Ajax or jQuery. For that purpose you have to use `event delegation`. And you can use `$.on` for that purpose.

Check documentation of $.on

You can use `$.live` but $live is depreciated. use $.on instead. Equivalent syntax of $.on for $.live and $.delegate which does the same thing

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

In this case event handler will be bound to `document`. And events will be delegated to target element by jQuery in this case `test` class.

UPDATE

I would suggest you to use `$.on` for all event handling purposes as all other methods routes through `$.on` and `$.off` method under the hood.

Check the definition of these functions from jQuery source v.1.7.2

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 );
} 

And that is true for these convenient events handlers too

blur focus focusin focusout load resize scroll unload click dblclick mousedown 
mouseup mousemove mouseover mouseout mouseenter mouseleave change select 
submit keydown keypress keyup error contextmenu

You can see all methods are using `$.on` and `$.off` themselves. So using `$.on` you can at least save a function call though which isn't that significant in most of the cases.

Problem

Let's say I have some of links that I want to add a javascript action to: ``` <a class='test'> <a class='test'> <a class='test'> ``` When my page loads I give them all a click event: ``` $('.test').click(function(){ alert("I've been clicked!") }); ``` but let's say afterward I add another element and I want to give it the same event. I can't do this: ``` $('.test').click(function(){ alert("I've been clicked!") }); ``` because then the first 3 will have 2 events on them. What's the best way to deal with this?

Original source

Related problems