3
var tableData = document.getElementsByTagName("td");

for(var i = 0; i < tableData.length; i++){
    var x = tableData[i];
    x.addEventListener("click", fun1(x.textContent));
}
function fun1(y){
    document.getElementById("testB").textContent = y;
}

I am trying to add a click function to every cell in a dynamically created table (i have no way of knowing how many cells are in the table or what their id would be but i only need the text contained in the cell)

I want to update a button with the content of the cell and as of right now it does not update on click and instead updates the button to the last value of the table.

I am fairly new to JavaScript and would appreciate any help you could offer.


here is the solution i used thanks to the answer provided below


var tables = document.getElementsByTagName("table");
for(var i = 0; i < tables.length; i++){
    tables[i].addEventListener("click",
    function(e) {
        if(e.target && e.target.nodeName == "TD") {
            fun1(e.target.textContent);
        }
     }
);
}
function fun1(y){
    document.getElementById("testB").textContent = y;
}

i went with this solution because the script generating the tables is not mine and as such i do not know what the id of the table i want is and do not know how many tables it actually creates.

Blake
  • 151
  • 1
  • 9

2 Answers2

3

You almost certainly do not want to add an event handler individually to each table cell if all (or even many) of them should do the same thing when clicked.

The DOM event model was designed to support delegation, which is a much better solution in cases like this. In brief: individual cells do not respond to clicks, but some ancestor element that is considered a permanent fixture (say, the <table> they are in) detects the clicks on cells and responds to them appropriately.

Here's how to set up delegation:

document.getElementById("#mytable").addEventListener("click",
    function(e) {
        if(e.target && e.target.nodeName == "TD") {
            fun1(e.target.textContent);
        }
     }
);

Of course you can choose any ancestor element you want, even <body> if that's what is required. Also note that this way of doing things means your code behaves as expected even while cells are added to or removed from the table -- you just do this once on page initialization.

Community
  • 1
  • 1
Jon
  • 396,160
  • 71
  • 697
  • 768
1
x.addEventListener("click", fun1(x.textContent));

This line is your issue -- addEventListener looks for a function reference, you're just calling the function (which does not return a function). Wrap it in an anonymous function, or bind the value to the reference.

x.addEventListener("click", function() { 
    fun1(x.textContent)
}, false); //also a good idea to add the event bubbling boolean param

Alternatively, ES6 arrow syntax:

x.addEventListener("click", () => fun1(x.textContent), false);
Sterling Archer
  • 20,452
  • 15
  • 77
  • 107