JQuery:.live()vs .delegate()用于ajax:替换元素的完整事件

时间:2012-07-05 15:50:05

标签: jquery ruby-on-rails

我在Ruby on Rails 3.0.7应用程序中使用jQuery 1.6.2并希望从.live()切换到.delegate()(计划升级到jQuery 1.7并使用{{1} })。我正在使用Rails中的.on()选项发送ajax请求并尝试使用:remote => true事件为响应设置处理程序。这些ajax请求通常会删除/替换实际触发请求的元素。

我遇到的问题是,如果一个元素被ajax请求替换,ajax:complete似乎在请求完成时会触发.live()处理程序,但ajax:complete会不(也是,我对jQuery 1.7进行了一些实验,发现.delegate()也不起作用。)

基本上,如果替换了.on()元素,则可以使用:

ajax_link

但这不是:

$(".ajax_link").live("ajax:complete", function(){
  //Do something...
});

有关为何发生这种情况的任何想法?我在其他地方看到$("body").delegate(".ajax_link", "ajax:complete", function(){ //Do something... }); 在幕后使用.delegate()所以这种行为让我感到惊讶。此外,欢迎任何有关更好地解决此问题的方法的建议。

1 个答案:

答案 0 :(得分:3)

使用jquery 1.7和1.8,从被删除的元素触发事件不会冒泡到文档。因此,不会调用在bodydocument上注册的回调处理程序。

要解决此问题,您必须:

  1. 在没有选择器的情况下注册您的complete回调:

    $(document).on('ajax:complete', function() {
      // do something
    });
    
  2. 修补handleRemote中的rails.js函数,以便在元素与文档分离时触发document上的事件。

    取代:

      complete: function(xhr, status) {
        element.trigger('ajax:complete', [xhr, status]);
    

    使用:

      complete: function(xhr, status) {
        if (element.parents().last().parent().get(0) == document)
          element.trigger('ajax:complete', [xhr, status]);
        else
          $(document).trigger('ajax:complete', [xhr, status]);
    
  3. 我对此issue #223 of rails-ujs发表评论。