Получение плагина jQuery timeago для распознавания недавно загруженных элементов DOM - PullRequest
5 голосов
/ 22 ноября 2010

Я использую плагин jquery timeago в моем приложении Rails 3.У меня есть раздел комментариев к моим сообщениям # show view, который автоматически обновляется каждые 30 секунд с помощью AJAX, используемого в эпизоде ​​Railscasts # 229 "Опрос на изменения" .Часть _comment, загружаемая jQuery, содержит время создания комментария, которое использует вспомогательный метод timeago Rails для создания тегов attr с правильным форматом времени.

Когда комментарий отправляется и ajax загружает комментарий, новый элемент DOM комментария не распознается плагином jQuery timeago.Таким образом, вместо времени комментария, отображаемого как «около минуты назад», он отображает «2010-11-21 23:08:36 UTC».

Я, конечно, гуглил эту проблему и нашел предложенияотносительно использования .live (), .delegate () или плагина livequery.

comments / index.js.erb:

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

comments / 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 для опроса и времени работает хорошо везде, только когда я делаю комментарий, и этот комментарий появляется вместе с AJAX от другогобраузер, с которым я столкнулся в этой проблеме.Любые предложения, ресурсы или код сделают мою неделю.Спасибо за чтение моего поста.

Ответы [ 2 ]

15 голосов
/ 21 февраля 2011

Ваш код вызывает $("abbr.timeago").timeago(); в блоке скрипта в шаблоне приложения. Он запускается при первой загрузке страницы и позволяет использовать функцию timeago для соответствующих элементов, существующих в данный момент. Любые совпадающие узлы, которые добавляются динамически позже - например, ваш AJAX-частичный - делают , а не , получают функцию timeago.

Один из вариантов - снова вызвать $("abbr.timeago").timeago() после добавления динамического контента. Тем не менее, это может быть трудно отследить и не забыть сделать, когда вы добавляете новую функциональность, поэтому я использую плагин livequery . Включите скрипт livequery на своей странице и замените $("abbr.timeago").timeago(); на следующее:

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

Это позволяет использовать время для любых совпадающих узлов, теперь и совпадающие узлы добавляются динамически.

4 голосов
/ 04 июля 2015

Как только load() сделал свое дело, вызывается 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().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...