2012-11-07 64 views
0

如果我創建像這樣在循環一堆對象:如何將值傳遞給jQuery單擊回調?

for(var i = 0; i < 5; i++) 
{ 
    var data = { val: i * 2 }; 
    var obj = $('<li>Item</li>'); 

    $("ul").append(obj); 

    obj.click(function() 
    { 
     alert(data.val); 
     // Output is 8 for all items. 

    }); 
} 

我只能夠在.click()處理程序中訪問的最後創建data對象。

如何在我的處理程序中引用相關的data對象 - 與jQuery對象被單擊同時創建的對象?

我已經能夠通過在jQuery對象上通過.attr()分配隨機屬性來保存數據,而不是單獨的對象,但我想遠離這種方法。

我也試過,但沒有運氣:

var data = { val: i * 2 }; 
var obj = $('<li>Item</li>'); 

obj.data = data; 

obj.click(function() 
{ 
    // 'data' is undefined here i.e. not associated with $(this). 
    alert($(this).data.val); 

}); 
+0

您需要使用封閉。 HTTP://計算器。COM /問題/ 7958613/jQuery的循環中,點擊關閉 – specialscope

回答

2

與第一例子的問題是由變量的作用域模糊。在JS所有變量具有的功能範圍,以重寫代碼表明,更明確地將導致:

var i,data,obj; 
for(i = 0; i < 5; i++) { 
    data = { val: i * 2 }; 
    obj = $('<li>Item</li>'); 

    $("ul").append(obj); 
    obj.click(function() { 
     alert(data.val); 
    }); 
} 

現在它更明顯,data內環路僅僅是一個變量,而不是一個新的每次迭代(如將在Java,C#等)。在click處理程序使用此變量時傳遞的匿名函數將關閉它。其結果是使用當函數爲執行時變量的當前值,而不是該函數被指定爲點擊處理函數時該變量所具有的值。

要解決這個問題,您可以將數據附加到元素本身。

在你的代碼中,你做了obj.data = ...然而,它將值附加到選擇而不是元素。下次你選擇相同的元素時,你有一個沒有data.property的新對象。相反,您可以使用jQuery .data()方法。

obj.data('key',data); 
obj.click(function() { 
    alert($(this).data('key').val); 
}); 

或者如果您想要將值嵌入到函數中,您可以使用自執行函數來執行該操作。當您將變量作爲參數傳遞給函數時,您正在使用當前值而不是關閉變量。

var i, 
    data, 
    obj, 
    createClick = function(data) { 
     return function(){ 
      alert(data.val); 
     }; 
    }; 
for(i = 0; i < 5; i++) { 
    data = { val: i * 2 }; 
    obj = $('<li>Item</li>'); 

    $("ul").append(obj); 
    obj.click(createClick(data)); 
} 

注意 順便說一句,你應該養成把{在一行沒有開始時結束的習慣。如果{位於下一行,則冒號插入可能會產生一些意外的結果。 E.g

return 
    { 
     val : 1 
    } 

可能返回undefined因爲分號可能return忽略對象文本

2

您可以使用jQuery的。數據()方法後插入。 http://api.jquery.com/data/

例如:

for(var i = 0; i < 5; i++){ 
    var obj = $('<li>Item</li>'); 
    obj.data('myData', {first: i * 2, second: i * 3}); 

    $("ul").append(obj); 

    obj.click(function(){ 
     alert($(this).data('myData').first); 
     alert($(this).data('myData').second); 
    }); 
} 
相關問題