简体   繁体   English

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

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

I'm using the jquery timeago plugin in my Rails 3 application. 我在Rails 3应用程序中使用jquery timeago插件 I have a comments section on my posts#show view that automatically refreshes every 30 seconds with the AJAX used in Railscasts episode #229 "Polling for Changes" . 我在我的posts#show视图上有一个注释部分,该部分会随着Railscasts第229集“投票更改”中使用的AJAX自动每30秒刷新一次。 The _comment partial that is loaded by jQuery contains the created_at time of the comment which uses the timeago Rails helper method to create attr tags with the correct time format. jQuery加载的_comment部分包含注释的created_at时间,该注释使用timeago Rails帮助器方法创建具有正确时间格式的attr标签。

When a comment is submitted and ajax loads the comment, the new comment DOM element isn't recognized by the jQuery timeago plugin. 当提交评论并用ajax加载评论时,jQuery timeago插件无法识别新的评论DOM元素。 So instead of the time of the comment being displayed as "about a minute ago" it displays "2010-11-21 23:08:36 UTC". 因此,显示的时间不是“大约一分钟前”,而是显示为“ 2010-11-21 23:08:36 UTC”。

I've googled this problem of course and found suggestions regarding the use of .live(), .delegate() or the livequery plugin. 我已经用谷歌搜索了这个问题,当然发现了有关使用.live(),.delegate()或livequery插件的建议。

comments/index.js.erb: 评论/index.js.erb:

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

comments/show.js.erb: 评论/show.js.erb:

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

public/javascripts/application.js: 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: 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: 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: 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: 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>

The AJAX polling and timeago plugin functionality works fine everywhere else, it's just when I make a comment and that comment appears with AJAX from another browser that I run into this issue. AJAX轮询和timeago插件功能在其他任何地方都可以正常使用,只是在我发表评论时,该评论与AJAX一起出现在我遇到此问题的其他浏览器中。 Any suggestions, resources or code would make my week. 任何建议,资源或代码都会使我很忙。 Thank you for reading my post. 感谢您阅读我的帖子。

Your code calls $("abbr.timeago").timeago(); 您的代码调用$("abbr.timeago").timeago(); in a script block in the application template. 在应用程序模板的脚本块中。 This runs as the page is loaded for this first time, and enables timeago functionality on matching elements that exist at that moment. 这是在首次加载页面时运行的,并为当时存在的匹配元素启用了timeago功能。 Any matching nodes that are added dynamically later on -- for instance your AJAX partial -- do not get timeago functionality. 稍后动态添加的任何匹配节点(例如您的AJAX局部节点)都不会获得timeago功能。

One option is to call $("abbr.timeago").timeago() again after adding dynamic content. 一种选择是在添加动态内容后再次调用$("abbr.timeago").timeago() However, that can be hard to keep track of and remember to do as you add new functionality, which is why I use the livequery plugin instead. 但是,在添加新功能时可能很难跟踪和记住要做的事情,这就是为什么我改用livequery插件 Include the livequery script in your page and replace $("abbr.timeago").timeago(); 在页面中包含livequery脚本,并替换$("abbr.timeago").timeago(); with the following: 具有以下内容:

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

This enables timeago on any matching nodes now and matching nodes added dynamically. 这将在当前任何匹配的节点上启用timeago, 动态添加匹配的节点。

Once load() has done its thing, ajaxComplete() is called. 一旦load()完成其工作, ajaxComplete()调用ajaxComplete() I would advise creating a function called ready_or_not() : 我建议创建一个名为ready_or_not()的函数:

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

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

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

There may be certain code that you only want to run when the document is ready, or when Ajax is complete. 可能只有您准备好文档或Ajax完成时才需要运行某些代码。 But for both, put it inside the ready_or_not() function. 但对于两者,都将其放在ready_or_not()函数中。

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

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