2013-12-12 99 views
2

我需要在我的文檔中添加一些按鈕,並使它們調用getTest()函數。所以1個按鈕應該叫getTest(1),第二個 - getTest(2)等等。但是一旦腳本完成後,事件監聽器僅附加到循環中的最後一個按鈕。無法將事件偵聽器附加到動態創建的按鈕

window.onload = function() { 
     var button_place = document.getElementById("buttons_here"); // get an element 

     /* add the event listeners */ 
     var i = 0; 
     while(i < 10) { 
      var cur_i = i + 1; 
      var current_but_name = "but_" + (i + 1); 
      button_place.innerHTML += "<button class=button id='" + current_but_name + "'>" + cur_i + "</button>\n"; 
      var bu = document.getElementById(current_but_name); 
      //bu.style.color = "#F00"; 

      bu.addEventListener("click", function() { 
       getTest(cur_i); 
      }); 

      ++i; 
     } 
    } 

我該如何處理?我如何將一個事件監聽器附加到我創建的每個按鈕上?

回答

4

這是因爲附加的循環是同步的,完成並且cur_i的值始終是發生點擊時迭代器的最後一個值。您需要將其包裝到本地範圍中。

(function(cur_i){ 
    bu.addEventListener("click", function() { 
     getTest(cur_i); 
    }); 
}(cur_i)); 

這將確保該值在綁定時是正確的。

你真的應該使用document.createElement來代替,並將事件直接附加到元素上,而不是通過較慢的DOM。


innerHTML是不可改變的,每+=你做什麼,再現了一大堆所以在每次迭代,你正在破壞舊的/先前的元素,並重新加入他們,但沒有他們的事件處理程序!

+0

+1。最後一部分回答了OP的原始問題,但第一部分解決了代碼中的另一個問題。 –

+0

非常感謝,它幫助了我。我無法理解語法:'(function(x){/*...*/}(x))是什麼? – Netherwire

+0

@RomanChehowsky:它是[IIFE](http://en.wikipedia.org/wiki/Immediately-invoked_function_expression)。它基本上創建一個函數並立即執行它。正如@Dimitar所說,它通過爲循環的每次迭代創建一個單獨的作用域來解決「cur_i始終是最後一個值問題」。 –

相關問題