JQuery将click事件绑定到带有参数的附加元素

时间:2011-01-02 03:53:54

标签: javascript jquery append bind

我正在尝试使用一些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 个答案:

答案 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并将其绑定到变量索引,这样当单击甚至发生时,它不会使用循环结束时的剩余值,而是在绑定时使用它的值。