Автоматическое обновление — ключевое преимущество timeago.js перед
простым вызовом format. Функция render
встраивает механизм таймеров, который поддерживает актуальность
отображаемых временных меток без участия разработчика.
При вызове render(nodes, locale):
import { render } from 'timeago.js';
const nodes = document.querySelectorAll('time[datetime]');
render(nodes, 'ru');
После этого вызова обновления происходят автоматически.
Интервал обновления зависит от текущего временно́го отрезка:
| Текущее отображение | Интервал обновления |
|---|---|
| “только что” / секунды | ~10 секунд |
| Минуты | ~1 минута |
| Часы | ~1 час |
| Дни и более | ~1 день |
Это предотвращает избыточные обновления для старых дат.
<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 для обновления только
видимых элементов.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 секунд назад"