2013-10-30 69 views
0

我動態附加一些div的jQuery和希望每一個附加click事件,這是我要做的事動態添加的DIV和附加事件

for (var i=0; i<CAItems.length; i++) 
    { 
     //alert(i); 
     $('#UserWorldItems').append(
      $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
       CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
       CAItems[i].Action + "</div></div>").on("click" , function() { alert(i); }) 
     ); 
    } 

創建的div但事實就是功能當點擊任何新的div導致出現警告「11」(11是i的最後一個值)時觸發。我怎樣才能解決這個問題,每個div都會顯示正確索引的提示? (0,1,2,3 .... 11)

+0

讓周圍的varialbe'一個封閉i'的 – andlrc

+0

可能重複(http://stackoverflow.com/questions/111102/how- [如何JavaScript的關閉工作?] do-javascript-closures-work) – andlrc

回答

0

您必須使用參數i創建一個函數來創建範圍,並在點擊完成時返回要執行的函數。看到你正在執行一個帶有參數i的匿名函數,即循環中i的值。就像它是一個副本,警報將具有正確的值。在你的情況下,for以最後一個值結束,當你點擊時,你看到的總是相同的,因爲你要求的是i的值,現在你有一個新的變量,並且有一個不同的函數範圍。

for (var i=0; i<CAItems.length; i++) 
{ 
    //alert(i); 
    $('#UserWorldItems').append(
     $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
      CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
      CAItems[i].Action + "</div></div>").on("click" , function (i) { return function() { alert(i); }; }(i)) 
    ); 
} 
+0

很棒!謝謝! – Shai

0

解決此問題的更好方法是將事件委託給靜態父級。

$('#UserWorldItems').on('click', '.UserItem', function(e){ 
    e.preventDefault(); 

    // Your code 
    // 'this' is set to the .UserItem element that was clicked 
}); 

當然,你將無法得到的i值,但你可以添加在data-*屬性(或通過.data()法),如果這就是你真的是以後什麼。

添加數據和存儲索引:

$("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
     item.Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
     item.Action + "</div></div>").data('index',i); 

,並檢索:

$(this).data('index'); 
+0

downvote解釋? – ahren

+0

這很好,但是我們認爲重點是如何使變量關閉,然後如何優化代碼...... – andlrc

+0

如果某人在錯誤的花園中導致某人沿着花園路徑前進,那麼沒有任何用處。我建議更好的做事方式。 – ahren

0

您需要的變量i圍繞一個封閉:

.on("click" , function(i) { return function() { alert(i); } }(i)) 
0

我會建議這樣做:

// Make a function called createDiv, 
// The arguments to the function is: item, index 
var createDiv = function(item, i) { 
    $('#UserWorldItems').append(
     $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
      item.Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
      item.Action + "</div></div>" 
     ).on("click" , function() { 
      alert(i); 
     }) 
    ); 
}; 
// Iterate your array and call createDiv: 
for (var i=0; i<CAItems.length; i++) { 
    createDiv(CAItems[i], i); 
} 
// Actually now you can use: 
// CAItems.forEach(createDiv); 
0

有幾種方法可以改進代碼的設計和效率。首先,jQuery append函數大致爲80% slower,而不是連接到一個字符串,然後一次追加整個事物。然後,爲了進一步清理代碼,爲了便於閱讀,可以在追加後綁定事件。

var html = ""; 

for (var i = 0; i < CAItems.length; i++) { 
    html += "<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" 
     + CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" 
     + CAItems[i].Action + "</div></div>"; 
} 

$('#UserWorldItems').append(html); 
$('#UserWorldItems .UserItem').click(function() { 
    var id = this.id; 
    var i = id.substring(id.length - 1); 
    alert(i); 
} 

或者,您可以添加一個valueitem屬性,每個div元素,然後很容易地通過jQuery的attr()功能訪問它,因爲你可能並不需要爲每格一個完全獨立的ID,但我不不知道你在努力達成什麼,所以也許你會這麼做。因此,它應該是這樣的:

var html = ""; 

for (var i = 0; i < CAItems.length; i++) { 
    html += "<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" 
     + CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" 
     + CAItems[i].Action + " item='" + i + "'</div></div>"; 
} 

$('#UserWorldItems').append(html); 
$('#UserWorldItems .UserItem').click(function() { 
    alert($(this).attr('item')); 
}