在新的前置项目上找到li

时间:2011-08-14 01:46:54

标签: jquery

我的应用程序使用.prepend()向<ul>添加新帖子,然后使用.ajax()函数将其添加到数据库中,如下所示:

$("#add input[type=submit]").click(function(){
    newPost = $("#add textarea").val();
    $.ajax({
        type    : "POST", 
        url     : "/add", 
        data    : { "post" : newPost },
        success: function(data) {               

           $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
        }
});

这可以按预期工作,但正如您所看到的,每个帖子都有一个删除按钮,我使用以下jquery删除帖子:

$(".delete").click(function(){
    var thiscache = $(this),
    post_id = thiscache.closest("li").find("p").attr("id");

    $.ajax({
        type    : "POST", 
        url     : "/delete", 
        data    : { "post_id" : post_id },

        success : function(r){ 
            thiscache.parent().slideUp('slow'); 
            },

    });
});

删除将适用于之前添加的帖子,但如果您使用ajax表单添加帖子,并单击删除则不会触发。可能是什么原因造成的?也许新帖子<li>不在DOM中?

我创建了一个没有Ajax函数的JSfiddle。 http://jsfiddle.net/bhhgf 如果您添加新帖子,它会附加它,但您无法删除它。删除当前发布的工作正常。

编辑:

我也使用自定义事件进行jeditable,但.live()不会触发新帖子。

$("p").editable('/edit/save', {event : 'edit_button'});

$(".edit").live('click', function(){       
    $(this).closest("li").find("p").trigger('edit_button');
});

4 个答案:

答案 0 :(得分:3)

您应该使用jQuery live()函数。这将把处理程序应用于与给定选择器匹配的所有当前和未来元素。因此,附加到文档的新元素将把处理程序附加到click

 $(".delete").live('click', function(){
   var thiscache = $(this),
   post_id = thiscache.closest("li").find("p").attr("id");

   $.ajax({
      type    : "POST", 
      url     : "/delete", 
      data    : { "post_id" : post_id },

      success : function(r) { 
          thiscache.parent().slideUp('slow'); 
      },
   });
 });

或者,您可以在添加新元素时添加处理程序,例如:

 var deleteHandler = function() {
   var thiscache = $(this),
   post_id = thiscache.closest("li").find("p").attr("id");

   $.ajax({
      type    : "POST", 
      url     : "/delete", 
      data    : { "post_id" : post_id },

      success : function(r) { 
          thiscache.parent().slideUp('slow'); 
      },
   });
 });

 $(".delete").click(deleteHandler);

 $("#add input[type=submit]").click(function(){
   newPost = $("#add textarea").val();
   $.ajax({
     type    : "POST", 
     url     : "/add", 
     data    : { "post" : newPost },
     success: function(data) {               

     el = $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
     el.find('.delete').click(deleteHandler);
   });
 });

这种方法会在出现时有选择地添加处理程序。

答案 1 :(得分:2)

对于动态添加到DOM的元素,您需要将事件处理程序重新绑定到它们或使用.live.delegate

$(".delete").live('click',function(){

});

$("#posts ul").delegate(".delete","click",function(){

});

jquery live

jquery delegate

对于您的第一个edit回调中的ajax链接再次调用所需元素上的jeditable

    $("#add input[type=submit]").click(function(){
        newPost = $("#add textarea").val();
        $.ajax({
            type    : "POST", 
            url     : "/add", 
            data    : { "post" : newPost },
            success: function(data) {               

               $('#posts ul').prepend('<li id="1234"><p>'+newPost+'<p><span class="delete">Delete</span></li>');
             //call editable here on the desired elements
             $("p").editable('/edit/save', {event : 'edit_button'});
            }
    });

答案 2 :(得分:1)

click事件仅限于当时存在的元素。之后添加的元素不受影响。

使用delegate方法将事件处理程序绑定到父元素,以便处理来自新添加元素的事件:

$("'#posts ul").delegate(".delete", "click", function(){
  ...

编辑:

可编辑插件不适用于delegate,因为它不仅仅是一个事件处理程序。添加后,您必须将其应用于list元素:

$("#" + id + " p").editable('/edit/save', {event : 'edit_button'});

其中id包含您前置的列表元素的ID。 (示例中为"1234",但您的实际ID不应只是数字...)

答案 3 :(得分:0)

好吧,你需要像之前的海报一样使用直播活动,但你的add方法中也有一个错误,因为你把id属性放在li元素上,但在你的html中,你有id属性on p元素。