如果我像这样在循环中创建一堆对象:
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.
});
}
我只能访问data
处理程序中最后创建的.click()
对象。
如何引用处理程序中的相关data
对象 - 与单击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);
});
分配jQuery对象的随机属性来保存数据而不是单独的对象,但我想摆脱这种方法
我也试过这个,但没有运气:
{{1}}
答案 0 :(得分: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#等)。单击处理程序使用此变量时传递的匿名函数将关闭它。结果是使用函数执行时变量的当前值,而不是当函数被指定为单击处理程序时变量的值。
要解决此问题,您可以将数据附加到元素本身。
在您的代码中,您执行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
忽略对象文字之后可能会插入一个分号
答案 1 :(得分:2)
您可以使用jQuery .data()方法。 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);
});
}