1

I've run into a Javascript/JQuery issue I was hoping you'd know how to solve.

Suppose I define this function that builds a table inside of the 'div' with id 'TableHolder':

MakeTable = function()
{
    document.getElementById('TableHolder').innerHTML = "";
    var tablebuild = "<table><tbody><tr>";
    for (i=0; i<3; i++)
    {
        tablebuild += "<td></td>";
    }
    tablebuild += "</tr></tbody></table>";
    document.getElementById('TableHolder').innerHTML = tablebuild;
}

I call this function when the document is ready, and tell JQuery to rebuild the table when any cells are clicked.

$(document).ready(function() {
    MakeTable();
    $('td').click(function(){
        MakeTable();
    }
});

Once a cell is clicked and MakeTable() rebuilds the table, the JQuery no longer works for the new cells.

Is there any way to fix this issue without using a loop?

*The above is a bread and butter version of a program that actually has a purpose, and I recognize it's useless as presented. Yet, the solution applies across the board.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user3225395
  • 581
  • 6
  • 23

2 Answers2

3

Yes, there is! You just need to use an event binding technique that will work for all elements now and in the future (since you are destroying and recreating the table and its children), using what is called event delegation. Here's how to hook it up with jQuery (using on()):

$(document).ready(function() {
    MakeTable();
    $('#TableHolder').on('click', 'td', function() {
        MakeTable();
    });
});

This delegates the click event within the TableHolder element to all current and future tds.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
0

The problem is because after rebuilding the table element in the MakeTable function, the td the click event is bound to doesn't exist any more.

You need to use a delegated event handler. Try this:

MakeTable();
$('#TableHolder').on('click', 'td', function(){
    MakeTable();
}

Also, you're using an odd mix of native JS and jQuery. Try this:

var MakeTable = function() {
    var $tableHolder = $('#TableHolder').empty();
    var tablebuild = "<table><tbody><tr>";
    for (i=0; i<3; i++)
    {
        tablebuild += "<td></td>";
    }
    tablebuild += "</tr></tbody></table>";
    $tableHolder.html(tablebuild);
}
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339