Lucas
Lucas

Reputation: 3004

Script Doesn't Detect Click on Created Element

I have a function that creates a span element with a removeme class and inserts it into the DOM. I also attach a click event to all spans with a class of removeme that should delete the span created in the previous step. This is not working. The click event isn't firing and the span is not being removed.

$('.createtext').click(function(){   
    $('<span class="removeme">Remove text</span>').appendTo($('#a1'));        
});

$('.removeme').click(function(){
    $('.removeme').remove();
});

I have an example here: http://jsfiddle.net/aagQE/

Upvotes: 1

Views: 400

Answers (5)

T.J. Crowder
T.J. Crowder

Reputation: 1075755

Because as of when you hook up your handler, the element doesn't exist. The code

$('.removeme').click(...);

...looks for matching elements that exist right then and hooks those elements up. Since you're creating the element later, it didn't exist when you did the hookup.

Either hook up the element when creating it (not really ideal), or use event delegation:

You can use event delegation via delegate or its global cousin, live (see also the new syntax below):

// delegate (preferred, see also newer syntax below)
$("#a1").delegate(".removeme", "click", function() {
    // ...
});

// live (not ideal, works all the way out at the document level)
$(".removeme").live("click", function() {
    // ...
});

As of jQuery 1.7, you can use the new on function, which unifies all the various forms of event hookup (direct and delegated):

// New syntax
$("#a1").on("click", ".removeme", function() {
    // ...
});

Note that the order of the arguments is slightly different from delegate.

What both delegate and on are actually doing is hooking the click event on the container element (#a1 in your case), and then when the click reaches that element, they look at the path from the actual bottom-most element actually clicked (event.target) up through the container to see if any of them matches the selector. If so, jQuery fires the event handler with this referencing the matched element rather than #a1.

Upvotes: 2

Spencer Ruport
Spencer Ruport

Reputation: 35117

I realize this isn't your actual question but, you know you can do this right?

$('.createtext').click(function(){   
    $('<span class="removeme">Remove text</span>')
        .click(function(){
            $(this).remove();
        })
        .appendTo($('#a1'));        
});

Upvotes: 1

Amadiere
Amadiere

Reputation: 11426

You can use the JQuery live function to access DOM elements that were not there at the initial load of the page.

e.g.

$('.createtext').live('click', function(){   
   $('<span class="removeme">Remove text</span>').appendTo($('#a1'));        
});

Upvotes: 0

James Hill
James Hill

Reputation: 61872

You need to use jQuery's .live() method to bind to events on dynamically created elements:

$('.removeme').live("click", (function(){
    $(this).remove();
});

As an alternative, if you're using jQuery 1.7, you could use the .on() method:

$(".removeme").on("click", function(event){
    $(this)remove();
});

Upvotes: 1

karim79
karim79

Reputation: 342775

Use event delegation:

$('.removeme').live("click", function(){
    $(this).remove();
});

or (better):

$('#a1').delegate(".removeme", "click", function(){
    $(this).remove();
});

Reference:

Upvotes: 3

Related Questions