1

I had an original HTML, say, like so:

<tr>
  <td class = 'greatTD' id = 'great1'>I am too great to be anything less.</td>
</tr>

Then I added an element through JavaScript like so:

function AddStuff()
{
    var s = '<tr><td class = "greatTD" id = "great2">I am even greater.</td></tr>';

    $('#foo').after(s);
}

function WireHandlers()
{
    $('.greatTD').click(GreatTDClickHandler);
}

function GreatTDClickHandler()
{
    // not being called for #great2
    // how do I make it be called?
}

$(document).ready(function() { WireHandlers(); });
Water Cooler v2
  • 29,006
  • 41
  • 139
  • 286

2 Answers2

3

The event handler is being assigned on load, before the .greatTD elements exist. Therefore you need to use a delegate handler, like this:

function WireHandlers() {
    $('#foo').on('click', '.greatTD', GreatTDClickHandler);
}

This attaches the event to the #foo element, which is present on load, and then filters it so that it's only executed on click of the .greatTD element.

Rory McCrossan
  • 306,214
  • 37
  • 269
  • 303
  • Wouldn't the `.greatTD` selector not find the element since it is inserted after `#foo`? – Danny Oct 09 '13 at 13:31
  • @Danny not at all, as it's interpreted when the element is clicked. – Rory McCrossan Oct 09 '13 at 13:32
  • Thanks, @RoryMcCrossan. What if the selector was not id-based like `#foo` but was a pseudo-selector like `table td tr:last`? – Water Cooler v2 Oct 09 '13 at 13:36
  • @WaterCoolerv2 that would work too, so long as the element selected is a parent of `.greatTD`. Ideally, it should be the closest parent which is available on page load. – Rory McCrossan Oct 09 '13 at 13:37
  • 1
    That's because the appended `tr` is not a child of `#foo`. Change it to `table` and it works: http://jsfiddle.net/cqbuR/1/ – Rory McCrossan Oct 09 '13 at 13:42
  • @RoryMcCrossan but isn't that what he is doing with the `$('#foo').after(s)`? Doesn't he want the click handler to work on `s`? I guess his example isn't big enough to get all the details... – Danny Oct 09 '13 at 13:51
  • 1
    Sorry for all the confusion. I just threw the `#foo` bit in to say that it is just *any* element. I did not want to suggest structure with regard to that selector. – Water Cooler v2 Oct 09 '13 at 14:00
1

The following should work.

$(document).on( 'click', '.greatTD', GreatTDClickHandler );

jQuery .on

Danny
  • 6,838
  • 8
  • 40
  • 65