Javascript 动态添加div和附加事件

Javascript 动态添加div和附加事件,javascript,jquery,events,html,Javascript,Jquery,Events,Html,我在JQuery中动态附加一些div,并希望每个div都附加一个click事件,我就是这样做的 for (var i=0; i<CAItems.length; i++) { //alert(i); $('#UserWorldItems').append( $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>

我在JQuery中动态附加一些div,并希望每个div都附加一个click事件,我就是这样做的

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

用于(var i=0;i您必须创建一个带有参数i的函数来创建作用域,并在单击完成时返回要执行的函数。请查看您正在执行一个带有参数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) )
    );
}

for(var i=0;i解决问题的更好方法是将事件委托给静态父级

$('#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);

在变量
i
周围需要一个闭包:

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

我建议这样做:

// 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);
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'));
}
//创建一个名为createDiv的函数,
//函数的参数是:item,index
var createDiv=函数(项,i){
$('#UserWorldItems')。追加(
$("" + 
item.Context+“”+
项目。操作+“”
).on(“单击”,函数(){
警报(一);
})
);
};
//迭代数组并调用createDiv:

对于(var i=0;i有几种方法可以提高代码的设计和效率。首先,jQuery append函数比串联到字符串然后一次追加整个内容要简单得多。然后,为了进一步清理代码,提高可读性,可以在追加后绑定事件

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

围绕变量做一个闭包BE
i
这一点的可能重复是好的,但我认为重点是如何在变量上做闭包,而不是如何优化你的代码……如果这是一个错误的花园,那么引导某人走上花园之路是没有用的。我建议一种更好的方法。你为什么认为
.data()
比variable scope好?因为它更慢?@BlueSkies-这实际上取决于OP创建的元素数量。事件处理程序越多,整个页面的运行速度就越慢。检索
数据的速度()
可以忽略不计,可读性是一个主要的优点。在上述情况下,速度尤其可以忽略不计,我使用
.data()存储变量
方法,而不是作为
数据-*
属性,因为jQuery将其存储在内部而不是节点上。第一篇文章没有给出任何理由。第二篇文章的理由是更多的内存使用意味着更慢的页面,这可能是真的。但是使用
.data()
也需要内存。这两篇文章都很旧。如果有什么区别的话,因为我们只是在讨论索引,我可能会直接将它放在元素上,而不是使用
.data()
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'));
}