使用jQuery将点击事件绑定到附加的带参数元素上

3

我正在尝试用一些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!");
}
5个回答

2

问题之一是变量i将始终是最后一个链接的变量,因为当用户单击任何链接时,循环将已经完成。解决此问题的一种方法是使用.data()方法将信息与每个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()(如问题和原始答案版本中所示)。请保留 HTML 标签。

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() 在刚创建的 <a> 上存储id
然后,使用那些存储的数据,我们可以将单个的事件处理器附加到 #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"等内容。你可以在这里的演示中测试所有上述内容

1

有几个问题。

首先,这不是你使用 .live() 的方式。 .live() 方法是针对给定选择器的 jQuery 对象调用的。您可以在任何时候执行此操作(甚至在 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 );     
});

现在,每个 link 的处理程序中都会有正确的 i 值。

0
LoadMailById(i);

i 在这里是一个引用,并在每个 for 循环中递增。因此,在 for 循环之后,它保持 size 的值;4。


0
   link.live('click', (function(index) {
        return function() { 
            LoadMailById(index);
        };
      )(i);
    });

我认为这应该可以解决问题。匿名函数将您的参数 i 绑定到变量 index,因此当单击事件发生时,它不会使用循环结束时剩余的值 i,而是使用绑定时的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接