我有一个问题 - 我想在创建它时向动态生成的表的每个单元格添加一个.onClick事件。
cell.onclick = function(){
mouseClick(row_number,i, cell);
};
但是,事件似乎只是添加到每行的最后一个单元格中。这怎么可能?它是否以某种方式压倒了以前的?以及如何使它工作?
function drawRow(rowData, length, keys, row_number){
//rowData - object where the row data is stored, length-row length, keys - object with table keys stored, row_number - number of the row
var rowData=rowData;
var row = document.createElement("tr");
for(i=0; i<length; i++){
var cell = document.createElement("td");
console.log("Creating event for "+i+" .");
cell.onclick = function(){
mouseClick(row_number,i, cell);
};
var key = keys[i];
var cell_text = document.createTextNode(rowData[key]);
cell.appendChild(cell_text);
row.appendChild(cell);
}
return row;
}
答案 0 :(得分:1)
您正在看到JavaScript-land中最常见的问题之一。
在之后完成for循环后,才会调用你的onclick函数。完成for循环后,i
的值为length
的值。只有这样你才能尝试阅读它。换句话说,你的每一个回调都说
function () {mouseClick(row_number, i, cell}
当你最终执行回调时,i
的值是它的最后一个值。
如果您使用的是ES6,请改写
for (let i=0; i<length; i++)
let
会为块的每个调用提供拥有的变量i
。在您的代码中,您只有一个i
在所有单元格中共享。这就是为什么所有细胞似乎都在做同样的事情!
如果您仍在ES5游戏中,请使用
替换代码的内部部分 cell.onclick = (function (j) {
return function () {
mouseClick(row_number, j, cell);
}
})(i);
这为每个回调函数提供了循环每个点i
的副本。第一次循环时,i
的值为0,您得到的回调是
function () {mouseClick(row_number, 0, cell}
循环的第二次迭代产生
function () {mouseClick(row_number, 1, cell}
等等!
非常酷......但是使用let
的ES6方式做同样的事情,更好一点。
(或者,有些方法可以在数组上使用forEach
方法执行此操作。这些方法还可以确保循环迭代不共享索引变量。)