动态添加DIV并附加事件

时间:2013-10-30 15:26:44

标签: javascript jquery events html

我在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时触发的功能会产生一个警告说&#34; 11&#34; (11是i的最后一个值)。如何解决此问题,每个div将显示具有正确索引的警报? (0,1,2,3 .... 11)

5 个答案:

答案 0 :(得分:0)

您必须使用参数创建一个函数来创建范围,并在完成单击后返回要执行的函数。看到您正在使用param 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) )
    );
}

答案 1 :(得分: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');

答案 2 :(得分:0)

您需要围绕变量i关闭:

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

答案 3 :(得分: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);

答案 4 :(得分:0)

有几种方法可以改善代码的设计和效率。首先,jQuery追加函数大约是80% slower,而不是连接到一个字符串,然后一次追加整个事物。然后,为了进一步清理代码,为了便于阅读,您可以在追加后绑定事件。

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()函数轻松访问它,因为您可能不需要完全独立的ID对于每个div,但我不知道你想要实现什么,所以也许你这样做。所以,它看起来像这样:

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