获取jQuery timeago插件来识别新加载的DOM元素

Bas*_*ect 5 javascript jquery ruby-on-rails jquery-plugins ruby-on-rails-3

我在我的Rails 3应用程序中使用了jquery timeago插件.我在我的帖子#review view上有一个评论部分,它使用Railscasts第229集"Polling for Changes"中使用的AJAX每30秒自动刷新一次.由jQuery加载的_comment部分包含注释的created_at时间,该时间使用timeago Rails帮助器方法以正确的时间格式创建attr标记.

提交注释并且ajax加载注释时,jQuery timeago插件无法识别新的注释DOM元素.因此,不是评论显示为"大约一分钟前"的时间,而是显示"2010-11-21 23:08:36 UTC".

我当然搜索了这个问题,并找到了关于使用.live(),. delegate()或livequery插件的建议.

评论/ index.js.erb的:

<% unless @comments.empty? %>
  $("#comments").append("<%=raw escape_javascript(render(@comments)) %>").timeago();
<% end %>
Run Code Online (Sandbox Code Playgroud)

评论/ show.js.erb:

$("#comments").append("<%=raw escape_javascript(render(@comments)) %>");
Run Code Online (Sandbox Code Playgroud)

公共/ Java脚本/ application.js中:

$(function() {
  if ($("#comments").length > 0) {
    setTimeout(updateComments, 30000);
  }
});

function updateComments () {
  var post_id = $("#post").attr("data-id");
  if ($("#comments").length > 0) {
    var after = $(".comment:last-child").attr("data-time");
  } else {
    var after = "0";
  }
  $.getScript("/posts/" + post_id + "/comments?after=" + after)
  setTimeout(updateComments, 30000);
}
Run Code Online (Sandbox Code Playgroud)

助手/ application_help.rb:

module ApplicationHelper
  def timeago(time, options = {})
    options[:class] ||= "timeago"
    content_tag(:abbr, time.to_s, options.merge(:title => time.getutc.iso8601)) if time
  end
end
Run Code Online (Sandbox Code Playgroud)

布局/ application.html.erb:

<!DOCTYPE html>
<html>
  <head>
    <%= stylesheet_link_tag 'style' %>
    <%= javascript_include_tag :defaults %>
    <%= javascript_include_tag 'jquery.timeago' %>
    <%= csrf_meta_tag %>
  </head>
  <body>
    <!-- ... -->
    <script type="text/javascript">
      $("abbr.timeago").timeago();
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

评论/ _comment.html.erb:

<div class="comment" data-time="<%= comment.created_at.to_i %>">
  <%- if comment.commenter.empty? -%>
  <%- else -%>   
    <span class="name">
      <%- if comment.email.blank? -%>
        <%= comment.commenter %>:
      <%- else -%>
        <a href="mailto:<%= comment.email %>"><%= comment.commenter %>:</a>
      <%- end -%>
    </span>
  <%- end -%>

  <%= simple_format @comment.body %>

  <span class="time">
    <%= timeago(comment.created_at) %>
  </span>
</div>
Run Code Online (Sandbox Code Playgroud)

文章/ show.html.erb:

<div id="post" data-id="<%= @post.id %>">
  <%= link_to @post.title, @post %>
  <%= simple_format @post.content %>

  <% unless @post.comments.empty? %>
    <div id="comments">
      <%= render @post.comments %>
    </div>
  <% end %>
</div>

<div id="replyform">
  <%= render "comments/form" %>
</div>
Run Code Online (Sandbox Code Playgroud)

AJAX polling和timeago插件功能在其他任何地方都能正常工作,就在我发表评论的时候,这个评论出现在另一个浏览器的AJAX中,我遇到了这个问题.任何建议,资源或代码都会成为我的一周.感谢您阅读我的帖子.

Joh*_*ohn 15

您的代码$("abbr.timeago").timeago();在应用程序模板的脚本块中调用.这是在第一次加载页面时运行,并在匹配当时存在的元素上启用timeago功能.以后动态添加的任何匹配节点 - 例如您的AJAX部分 - 都不会获得timeago功能.

一种选择是$("abbr.timeago").timeago()在添加动态内容后再次调用.但是,在添加新功能时,可能很难跟踪并记住这样做,这就是我使用livequery插件的原因.在页面中包含livequery脚本并替换$("abbr.timeago").timeago();为以下内容:

$("abbr.timeago").livequery(function () { $(this).timeago(); });
Run Code Online (Sandbox Code Playgroud)

这样可以立即在任何匹配节点上启用timeago,动态添加匹配节点.