0

如果我像这样在循环中创建一堆对象:

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 对象同时创建的对象?

过去,我可以通过在 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);

});
4

2 回答 2

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));
}

注意顺便说一句 ,您应该养成将{行尾而不是开头的习惯。{如果在下一行,半冒号插入可能会产生一些意想不到的结果。例如

return 
    {
      val : 1
    }

可能会返回,因为在忽略对象文字undefined后可能会插入分号return

于 2012-11-07T05:25:07.790 回答
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);
    });
}
于 2012-11-07T05:25:37.863 回答