2016-05-30 44 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

非常感謝! –

相關問題