繁体   English   中英

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

[英]Getting jQuery timeago plugin to recognize newly loaded DOM elements

我在Rails 3应用程序中使用jquery timeago插件 我在我的posts#show视图上有一个注释部分,该部分会随着Railscasts第229集“投票更改”中使用的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 %>

评论/show.js.erb:

$("#comments").append("<%=raw escape_javascript(render(@comments)) %>");

public / javascripts / 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);
}

helpers / 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

layouts / 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>

comments / _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>

posts / 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>

AJAX轮询和timeago插件功能在其他任何地方都可以正常使用,只是在我发表评论时,该评论与AJAX一起出现在我遇到此问题的其他浏览器中。 任何建议,资源或代码都会使我很忙。 感谢您阅读我的帖子。

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

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

$("abbr.timeago").livequery(function () { $(this).timeago(); });

这将在当前任何匹配的节点上启用timeago, 动态添加匹配的节点。

一旦load()完成其工作, ajaxComplete()调用ajaxComplete() 我建议创建一个名为ready_or_not()的函数:

$(document).ready(function(){
  ready_or_not();
});

$(document).ajaxComplete(function(){
  ready_or_not();
});

function ready_or_not(){
  $(".timeago").timeago();
}

可能只有您准备好文档或Ajax完成时才需要运行某些代码。 但对于两者,都将其放在ready_or_not()函数中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM