2012-02-22 92 views
1

我有一个表单提交消息。我想以AJAX的方式提交。下面的代码工作,但新添加“回复”按钮不起作用:如何使JavaScript工作,以响应以后以AJAX方式添加的按钮

 {% block body %} 
<script type="text/javascript" src="{{ url_for('static', filename='jquery.form.js') }}"></script> 
<script type="text/javascript"> 
    // wait for the DOM to be loaded 
    $(document).ready(function() { 
     $("#message_form").ajaxForm(function() { 
      var messageid = ''; 
      var messagepubdate = 0; 
      // GET NEWEST MESSAGE ID 
      $.getJSON($SCRIPT_ROOT + '/_get_new_message', function (data) { 
       messageid = data.messageid; 
       messagepubdate = data.messagepubdate; 
       //alert(messageid); //TESTED! the messageid is the newly added message's _id! 
       var div = document.createElement("div"); 
       div.innerHTML = "<li><img src='{{ g.get_user(g.user._id).email|gravatar(size=48)}}'><p> " + 
       "<strong><a href='{{url_for('user_timeline', username=g.user._id)}}'>{{ g.user._id}}</a></strong>&nbsp; " + $('#new_message').val() 
       + "<small>&mdash; " + messagepubdate + "</small><p align='right' style='text-align: right'><small><a href='#' data-messageid='#replies" + messageid + "' class='reply'>Reply</a></small></p><p><br /><div class='replies hidden' id='replies" + messageid + "'></div></p></p></li>"; 
       $('ul#messages').prepend(div); 
      }); 
      return false; 
     }); 
    }); 
</script> 

旧短信,下面的脚本能很好地切换的答复DIV:

<script type=text/javascript> 
    $(function() { 
     $('a.reply').click(function() { 
      messageid = $(this).attr('data-messageid'); 
      $(messageid).text('loading'); 
      $.getJSON($SCRIPT_ROOT + '/_get_replies', { messageid: messageid.substring(8) }, function (data) { 
       $(messageid).html(data.result); 
       $(messageid).slideToggle(0); 
      }); 
      return false; 
     }); 
    }); 
</script> 

回答

3

官方jQuery 1.7的答案是jQuery.on

您可以使用jQuery.on订阅任意事件,并且您可以使用jQuery.off取消订阅。

听取所有的点击匹配a.reply的元素,无论何时它被添加到文档中,你可以使用下面的代码:

$(document.body).on('click', 'a.reply', function() { /* ... */ }); 

同样,你可以使用

$('body').on('click', 'a.reply', function() { /* ... */ }); 

基本上,$('body')是添加了事件侦听器的上下文。所以实际上,jQuery正在等待任何事件冒泡到body元素,并检查该事件是否为click事件。如果是,并且点击事件的元素匹配a.reply选择器,那么jQuery将触发你传递的委托作为第三个参数。

如果我们只是做:

$('a.reply').on('click', function() { /* ... */ }); 

这将工作方式相同,但只由最初由a.reply选择选择元素生成的事件。因此,以后添加到dom中的任何新元素都不会包含在内。而且,因为我们没有在on方法中添加选择器,所以它不会侦听子事件。

编辑

在jQuery中的早期版本中,你可以使用jQuery.live,这在类似的工作,如果不是完全一样的时尚。在jQuery 1.7中,jQuery.live只是简单的包装jQuery.on

1

你想要使用live()函数并将click作为事件来处理。

.click()适用于目前存在

.live()适用于所有当前和未来对象的所有对象。

$('a.reply').live('click' , function (e){ ... }); 

更多阅读:http://api.jquery.com/live/

UPDATE

正如其他人所指出的那样,live()已被废弃,你应该使用on()

http://api.jquery.com/on/

+3

现场已被弃用(因为1.4.4版本!) – gdoron 2012-02-22 15:17:10

+0

好吧,我会的。我不知道。它仍然可以工作,并且与'.on()'函数具有相同的原理。这是很好,如果jQuery的网站更明显,除了标记为'弃用' – Dutchie432 2012-02-22 15:29:45

+0

请阅读你添加的[文档](http://api.jquery.com/live/),了解为什么'活着'是弃用。 – gdoron 2012-02-22 15:31:49

1

元素添加到DOM不得不 附加事件处理程序。您需要在AJAX调用之后附加它们,或者事先使用jQuery的.on().live()功能。

2

如果您需要将事件附加到将来可能添加的元素(通过Ajax),那么您应该始终使用事件委派。

简而言之,它的作用是将一个事件附加到父元素,然后检查以查看哪个孩子被点击。添加或删除子元素无关紧要。

jQuery中使用委派正确的方法是用。对()和.off()方法:

$("#dataTable tbody").on("click", "tr", function(event){ 
    alert($(this).text()); 
}); 

.live()和委托()赞成这个新语法已过时。

事实上,jQuery的现在只是径直通过对这些函数的调用来。对()和.off()

live: function(types, data, fn) { 
     jQuery(this.context).on(types, this.selector, data, fn); 
     return this; 
    } 

delegate: function(selector, types, data, fn) { 
     return this.on(types, selector, data, fn); 
    } 

注:这不仅是有用的Ajax应用程序。如果你有1000行,例如一个表,这是更为有效的方使用上表本身委派的事件,而不是附加到元素100S

一些进一步阅读:

相关问题