Автоматическое обновление элементов

Автоматическое обновление — ключевое преимущество timeago.js перед простым вызовом format. Функция render встраивает механизм таймеров, который поддерживает актуальность отображаемых временных меток без участия разработчика.


Как работает автообновление

При вызове render(nodes, locale):

  1. Каждый переданный элемент немедленно получает текст.
  2. Для каждого элемента создаётся таймер.
  3. Таймер срабатывает через адаптивный интервал и повторяет обновление.
import { render } from 'timeago.js';

const nodes = document.querySelectorAll('time[datetime]');
render(nodes, 'ru');

После этого вызова обновления происходят автоматически.


Адаптивные интервалы

Интервал обновления зависит от текущего временно́го отрезка:

Текущее отображение Интервал обновления
“только что” / секунды ~10 секунд
Минуты ~1 минута
Часы ~1 час
Дни и более ~1 день

Это предотвращает избыточные обновления для старых дат.


HTML-разметка для автообновления

<article>
  <h2>Заголовок поста</h2>
  <time class="post-time" datetime="2025-05-26T10:00:00Z"></time>
</article>

Атрибут datetime обязателен — именно его render читает.


Инициализация

import { render } from 'timeago.js';

document.addEventListener('DOMContentLoaded', () => {
  const nodes = document.querySelectorAll('.post-time');
  render(nodes, 'ru');
});

Обновление в реальном времени

Элемент “только что” через секунды начинает показывать “X секунд назад”, через минуту — “1 минуту назад”, затем — “2 минуты назад”, и так далее. Всё это происходит без перезагрузки страницы.


Обновление нескольких независимых групп

import { render } from 'timeago.js';

// Посты в ленте
render(document.querySelectorAll('.feed-time'), 'ru');

// Комментарии
render(document.querySelectorAll('.comment-time'), 'ru');

// Уведомления
render(document.querySelectorAll('.notification-time'), 'en_US');

Каждая группа обновляется независимо.


Автообновление при добавлении новых элементов

import { render } from 'timeago.js';

function addPost(post) {
  const li = document.createElement('li');
  li.innerHTML = `
    <h3>${post.title}</h3>
    <time class="post-time" datetime="${post.createdAt}"></time>
  `;

  document.getElementById('feed').prepend(li);

  // Подключить новый элемент к автообновлению
  render(li.querySelector('.post-time'), 'ru');
}

Обновление при возвращении из фона

Когда пользователь возвращается на вкладку, время могло устареть:

import { cancel, render } from 'timeago.js';

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') {
    const nodes = document.querySelectorAll('.time');
    cancel(nodes);
    render(nodes, 'ru');
  }
});

Остановка обновлений

import { cancel } from 'timeago.js';

// Остановить конкретные элементы
const nodes = document.querySelectorAll('.post-time');
cancel(nodes);

// Остановить все обновления
cancel();

Предотвращение дублирования таймеров

Если render вызывается дважды для одних элементов без cancel, таймеры дублируются:

// Неправильно
render(nodes, 'ru');
render(nodes, 'ru'); // два параллельных таймера!

// Правильно
cancel(nodes);
render(nodes, 'ru');

Автообновление и производительность

На странице с сотнями элементов каждый таймер — дополнительная нагрузка. Оптимизации:

  • Использовать IntersectionObserver для обновления только видимых элементов.
  • Устанавливать длинные интервалы для старых дат.
  • Применять виртуализацию для длинных списков.

Пример с IntersectionObserver

import { render, cancel } from 'timeago.js';

function lazyRender(nodes, locale = 'ru') {
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(({ target, isIntersecting }) => {
      if (isIntersecting) {
        render(target, locale);
      } else {
        cancel(target);
      }
    });
  }, { threshold: 0 });

  nodes.forEach(node => observer.observe(node));
}

Проверка работоспособности обновления

<time id="test" datetime=""></time>
import { render } from 'timeago.js';

document.getElementById('test').setAttribute('datetime', new Date().toISOString());

render(document.getElementById('test'), 'ru');

// Через 10 секунд элемент должен показать "только что" → "10 секунд назад"