我正在尝试使用一些li元素填充ul列表,并为每个li元素提供一个使用不同参数调用相同函数的链接。但它似乎不起作用,我附上了下面的代码,在文档加载时调用CheckForNewMail。有人可以帮帮我吗?
function CheckForNewMail() {
//////////////////////////////////////////////////////////////////
// This will be dynamic
MailInInbox[0] = new Array("0", "Mail One");
MailInInbox[1] = new Array("12", "Mail Two");
MailInInbox[2] = new Array("32", "Mail Three");
MailInInbox[3] = new Array("5", "Mail Four");
//////////////////////////////////////////////////////////////////////
$('#mail-in-inbox').children().remove();
size = 4; element = $('#mail-in-inbox');
for(i = 0; i < size; ++i) {
var link = $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>');
link.live('click', function() {
LoadMailById(i);
});
li = $('<li></li>');
li.append(link);
element.append(li);
}
}
function LoadMailById(id) {
alert("Button "+ id +" clicked!");
}
答案 0 :(得分:2)
一个问题是变量i
将始终是最后一个链接的变量,因为当用户点击任何链接时,循环就会完成。解决此问题的一种方法是使用.data()
method将一条信息与每个li
元素相关联:
link.data('mailId', i); // within the loop
然后,您可以为#mail-in-inbox
中的所有收件箱链接绑定单个事件处理程序:
$('#mail-in-inbox').on('click', '.inbox-link', function() {
LoadMailById($(this).data('mailId'));
});
编辑添加:jQuery 1.7中引入了.on()
。如果您使用的是jQuery 1.6或更早版本,请改用.delegate()
或.live()
(如问题和此答案的原始版本)。
答案 1 :(得分:2)
首先,我在这里做一个假设:
id
,而不是索引,例如0, 12, 32, 5
,而不是0, 1, 2, 3
。鉴于(如果假设不正确,可以使用.index()
轻松调整),您可以这样做:
function CheckForNewMail() {
MailInInbox[0] = ["0", "Mail One"];
MailInInbox[1] = ["12", "Mail Two"];
MailInInbox[2] = ["32", "Mail Three"];
MailInInbox[3] = ["5", "Mail Four"];
$('#mail-in-inbox').empty();
var size = 4, element = $('#mail-in-inbox');
for(i = 0; i < size; ++i) {
$('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>')
.data('id', MailInInbox[i][0]).wrap('<li/>').parent().appendTo(element);
}
}
这里有一些变化:
var
声明(如果它们尚未在别处定义).data()
将id
存储在我们刚创建的<a>
上然后,使用存储的数据,我们可以将单个处理程序附加到#mail-in-inbox
容器一个时间(在DOM就绪上),而不是一个每个 <a>
此函数运行的每个时间,它应该如下所示:
$('#mail-in-inbox').delegate('.inbox-link', 'click', function() {
alert("Button "+ $.data(this, 'id') +" clicked!");
});
这会显示"Button 0 clicked!"
,"Button 12 clicked"
等,You can test out all of the above in a demo here。
答案 2 :(得分:1)
有几个问题。
首先,这不是你使用.live()
的方式。针对给定选择器的jQuery对象调用.live()
方法。您可以在任何时候(甚至在DOM加载之前)执行此操作,并且页面上与选择器匹配的任何单击都将触发处理程序。
在你的情况下,它会像:
$('.inbox-link').live('click',function() {
// whatever
});
在您的情况下,如果您为每个项目分配了单独的处理程序,则可以使用.bind
代替live()
。
正如另一位用户所提到的,你在处理程序中没有i
的正确值。您可以使用$.each()
来克服此问题。
$.each(MailInInbox, function( i ) {
var link = $('<a href="#" class="inbox-link">'+ MailInInbox[i][1] +'</a>');
link.bind('click', function() {
LoadMailById(i);
});
$('<li></li>').append( link ).appendTo( element );
});
现在,每个i
的处理程序中都会有link
的正确值。
答案 3 :(得分:0)
LoadMailById(i);
i
是此处的引用,并在每次迭代时增加。因此,在for循环之后它保持大小的值; 4。
答案 4 :(得分:0)
link.live('click', (function(index) {
return function() {
LoadMailById(index);
};
)(i);
});
我认为这应该可以解决问题。匿名函数接受你的参数i并将其绑定到变量索引,这样当单击甚至发生时,它不会使用循环结束时的剩余值,而是在绑定时使用它的值。