2016-05-30 49 views
1

我遇到了一个问题 - 我想在创建动态生成的表格的每个单元格时添加一个.onClick事件。javascript - 给表单中的每个单元格添加.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

欢迎可怕的不方便世界封闭的;) –

+0

'我有一个全局范围(据我所知 - 顺便说一句,这是不好的做法),'row_number'和'cell'的作用域是外部函数,所以它们对所有单元格都是一样的。你可以[修复它与闭包](http://stackoverflow.com/q/750486/4642212),但我强烈建议**事件代表团**而不是。 – Xufox

+0

这个问题是这个问题的重复http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue 查看答案有一个可能的解决方案和javascripts臭名昭着的loop-closure问题的解释。 – juan8a

回答

1

你正在看到JavaScript-land中最常见的问题之一。

您的onclick函数直到之后才会被调用,for循环完成。当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} 

等等!

很酷......但ES6的方式与let做同样的事情,更好一点。

(或者,有办法做这件事情与阵列forEach方法,这些也保证了循环迭代不共享的索引变量。)

+0

不错的答案雷 - 还介意添加ES5解决方案?ES6还没有完全支持,并且OP很有可能没有使用ES6 –

+0

谢谢,好主意。 –

+0

非常感谢! –

相关问题