2012-12-26 64 views
2

我是JavaScript的新用戶。我想添加onclick事件到表格行。我沒有使用JQuery。JavaScript添加表格行onclick事件

我循環通過行並使用閉包來確保每行有外部函數的狀態。 循環工作。使用警報,我看到爲每次迭代分配的功能。但是當我點擊該行時,不會顯示任何提示。 下面是可以加載的HTML和代碼。

爲什麼表格行事件不起作用?

<!doctype html> 
<html lang="en"> 
<body> 
<script> 
function example4() { 
    var table = document.getElementById("tableid4"); 
    var rows = table.getElementsByTagName("tr"); 
    for (var i = 0; i < rows.length; i++) { 
     var curRow = table.rows[i]; 
     //get cell data from first col of row 
     var cell = curRow.getElementsByTagName("td")[0]; 
     curRow.onclick = function() { 
      return function() { 
       alert("row " + i + " data="+ cell.innerHTML); 
      }; 
     }; 
    } 
} 
function init() { example4(); } 
window.onload = init; 
</script> 
<div> 
Use loop to assign onclick handler for each table row in DOM. Uses Closure. 
    <table id="tableid4" border=1> 
     <tbody> 
     <tr><td>Item one</td></tr> 
     <tr><td>Item two</td></tr> 
     <tr><td>Item three</td></tr> 
     </tbody> 
    </table> 
</div> 
</body> 
</html> 
+1

你的函數內返回的功能。這需要'onclick'中的另一個函數來調用返回的函數。 – jeremy

+0

這個問題與封閉無關。 – Mathletics

+0

@Mathletics:我使用閉包,因爲我希望事件返回被點擊的行。在早期版本的代碼中,我總是得到第3行總是返回。我的理解是封閉將解決這個問題。 –

回答

9

這似乎是正規途徑

DEMO

function example4() { 
    var table = document.getElementById("tableid4"); 
    var rows = table.rows; // or table.getElementsByTagName("tr"); 
    for (var i = 0; i < rows.length; i++) { 
     rows[i].onclick = (function() { // closure 
      var cnt = i; // save the counter to use in the function 
      return function() { 
       alert("row"+cnt+" data="+this.cells[0].innerHTML); 
      }  
     })(i); 
    } 
} 
window.onload = function() { example4(); }​ 

UPDATE:@ParkerSuperstar建議,在我(我)是不必要的。 我還沒有測試過,但他的fiddle似乎工作。

+0

@mplungian:我試圖理解這是如何工作的。你做了兩件事。 1)你已經將外部函數包含在parens中並添加了一個參數i。 2)你在外部函數中將i保存爲cnt,所以現在內部函數會看到cnt。我不明白爲什麼內在功能沒有看到我。 –

+0

這正是封閉所要做的。第一個函數需要一個在內部函數 – mplungjan

1

我不太清楚你爲什麼要在這裏使用閉包,你可以更精緻一點嗎?

你沒有看到所需警報的原因是因爲在onclick函數中,你正在返回另一個函數。即:

window.onload = function() { 
    return function() { 
     alert("Closure... why?"); 
    }; 
}; 

像這樣的事情不會真的工作,因爲你永遠調用嵌套函數...嘗試不使用封閉或註釋解釋爲什麼你要關閉,因爲你沒解釋對我來說沒什麼意義。

+0

我想最終返回單擊行時的行信息。我想我在函數內部嵌套一個返回f()的方式使內部函數關閉了外部函數變量的作用域,從而使我可以訪問行信息。我想讓警報向我顯示這些信息。 –

0

你只需要去掉一個額外的功能和腳本會是這樣

<script> 
function example4() { 
    var table = document.getElementById("tableid4"); 
cells = table.getElementsByTagName('td'); 

for (var i=0,len=cells.length; i<len; i++){ 
cells[i].onclick = function(){ 
    alert(this.innerHTML); 

} 
} 
} 
function init() { example4(); } 
window.onload = init; 
</script> 
+0

內保持靜態的副本,這與我的回答有何不同(除了顯而易見的信息量較少的因素)? – jeremy

+0

這不是,也不會工作。它每次都會提醒row3 http://jsfiddle.net/mplungjan/zwW4a/ – mplungjan

+0

請嘗試更新代碼 –