3

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

我遇到的问题是,如果一个元素被 ajax 请求替换,.live()似乎ajax:complete在请求完成时无论如何都会触发处理程序,但.delegate()没有(另外,我对 jQuery 1.7 做了一些实验,发现它.on()不起作用任何一个)。

本质上,如果ajax_link元素被替换,这有效:

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

但这不会:

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

关于为什么会发生这种情况的任何想法?我在 SO 的其他地方读到了在幕后.delegate()使用的,所以这种行为让我感到惊讶。.live()此外,任何有关解决此问题的更好方法的建议都将受到欢迎。

4

1 回答 1

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]);
    

对 rails-ujs 的 issue #223发表了评论。

于 2012-09-11T08:11:07.993 回答