Javascript 动态添加div和附加事件
我在JQuery中动态附加一些div,并希望每个div都附加一个click事件,我就是这样做的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'>
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);
}
围绕变量做一个闭包BEi
这一点的可能重复是好的,但我认为重点是如何在变量上做闭包,而不是如何优化你的代码……如果这是一个错误的花园,那么引导某人走上花园之路是没有用的。我建议一种更好的方法。你为什么认为.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'));
}