0

我在 JQuery 中动态附加了一些 DIV,并希望为每个 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)

4

5 回答 5

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) )
    );
}
于 2013-10-30T15:29:13.543 回答
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');
于 2013-10-30T15:30:21.327 回答
0

你需要一个围绕变量的闭包i

.on("click" , function(i) { return function() { alert(i); } }(i) )
于 2013-10-30T15:31:31.410 回答
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);
于 2013-10-30T15:31:35.977 回答
0

有几种方法可以提高代码的设计和效率。首先,jQuery append 函数比连接到一个字符串然后一次性追加整个内容要慢大约 80% 。然后,为了进一步清理代码以提高可读性,您可以在附加后绑定事件。

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

或者,您可以为每个 div 元素添加一个valueitem属性,然后通过 jQuery 的attr()函数轻松访问它,因为您可能不需要每个 div 完全独立的 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'));
}
于 2013-10-30T16:06:59.387 回答