【问题标题】:When doing a .replaceWith() in jQuery the event bindings are not preserved在 jQuery 中执行 .replaceWith() 时,不会保留事件绑定
【发布时间】:2012-02-14 03:08:37
【问题描述】:

这是一个精简的例子。

请记住,.chat-reply 类绑定了一个点击事件处理程序。

HTML(回复按钮):

<div class="container">
    <a href="#" class="btn small chat-reply">Reply</a>
</div>

当有人单击另一个按钮时调用此jQuery函数,该按钮将消息发送到服务器以保存在数据库中。这是通过 ajax 完成的,并且成功完成。在前面提到的 .ajax() success() 回调中调用了这个函数:

$.ajax({
      type      :  'GET',
      url       :  '/some_controller/some_method',
      success   :  function(data) {

      $('.container').replaceWith(data);
    }
});

上述成功回调中的“数据”将替换 整个 .container div,包括子 .chat-reply 按钮。在这个 replaceWith() 之后,click 事件不再绑定到按钮上。

从逻辑上讲,我试图让最终用户将消息发布到时间线,然后在时间线中显示该消息而不需要刷新屏幕。

【问题讨论】:

    标签: jquery ajax event-handling replacewith


    【解决方案1】:

    抓取现在使用“on”绑定的 jquery 1.7:http://blog.jquery.com/2011/09/28/jquery-1-7-beta-1-released/

    或者如果

    旧 api 替换为在 DOM 更改后与实时类型事件处理程序绑定。

    这个 $(selector).live(events, fn)

    变成这个 $(document).on(events, selector, fn)

    或者在代码中

    这个

    $(".container a.chat-reply").live("click", function(){
     // do it live!
    });
    

    在 1.7 中变成这个

    $(".container").on("click", "a.chat-reply", function(event){
     // do it live!
    });
    

    通过各种选项来选择您想要的对象。

    【讨论】:

    • 您的代码示例让我有点困惑。如果你不介意澄清一点,那就太好了。
    • 抱歉,这个块只是从旧的“live”指向“on”,但 Vigrond 的例子是你如何做一个“on”。在回调中收到 html 后附加事件几乎会更好。
    【解决方案2】:

    在您的点击处理程序中,改为使用 .on() 作为委托

    $("div.container").on("click", "a.chat-reply", function(even){
      //click handler here
    });
    

    该事件将“冒泡”到容器中,如果它与 a.chat-replay 匹配,它将触发。

    【讨论】:

    • “冒泡”起作用了,但是一旦我执行 replaceWith(),那些事件绑定就消失了——仍然。
    • 当然。我的错,replaceWith 将替换整个元素。你可以改用 .html(content) 吗?这将替换它的内容,而不是 .container 元素。否则,您将不得不开始查看 .container 的祖先,以将 .on 事件处理程序附加到。
    • Ewww。那会变得很糟糕。我发现另一篇文章建议使用“连接”事件绑定的功能。然后在replaceWith() 之后再次调用它。它不漂亮,但我可能没有太多选择。
    • 此外,我考虑了 .html(content) 方法,但它在后端发生了太多其他事情,以使这种方法有效。
    • 这里是类似问题的链接:stackoverflow.com/questions/770308/…
    【解决方案3】:

    决定采用一个不太优雅的解决方案,部分原因是这篇文章:Events not registering after replaceWith

    我创建了一个名为 wireUpChatReply() 的函数,它将点击事件绑定到 .chat-reply 按钮。

    然后在replaceWith() 之后,我调用wireUpChatReply() 来重新绑定事件。我在 document.ready 上对wireUpChatReply 进行了同样的调用。

    它不漂亮,但它有效。

    【讨论】:

      【解决方案4】:

      关于实时事件的两个答案并不能解决问题,因为容器本身被替换并且事件绑定消失了。

      无需重新绑定事件,在这种情况下,您需要知道已经绑定的事件,您可以执行以下操作:

      $(".container").parent().on("click", ".container a.chat-reply", function(){
        // do something
      });
      

      或者,如果有多个容器:

      $(document.body).on("click", ".container a.chat-reply", function(){
        // do something
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多