Помимо основных функций (format, render,
cancel, register), в timeago.js есть
внутренние механизмы, которые можно использовать через обёртки или
изучить для создания расширений.
Официальный публичный API timeago.js:
| Метод | Назначение |
|---|---|
format |
Форматирование даты в строку |
render |
Автообновление DOM-элементов |
cancel |
Остановка автообновлений |
register |
Регистрация локали |
Служебных методов в публичном API нет. Все внутренние функции являются приватными.
Внутри библиотеки присутствуют:
toDate(input) — конвертация входного
значения в объект Date:
// Аналог внутренней реализации
function toDate(input) {
if (input instanceof Date) return input;
if (typeof input === 'number') return new Date(input);
return new Date(input);
}
formatDiff(diff, locale) — вычисление
строки по числовой разнице. Не экспортируется.
run(node, locale) — создание таймера
для одного элемента.
Можно создать набор утилит, дополняющих стандартные методы:
// src/timeago-utils.js
import { format } from 'timeago.js';
/**
* Форматирует дату относительно текущего момента с fallback.
*/
export function safeFormat(date, locale = 'ru', fallback = '') {
if (!date) return fallback;
const d = new Date(date);
if (isNaN(d.getTime())) return fallback;
return format(d, locale);
}
/**
* Возвращает метаданные вместе со строкой.
*/
export function formatWithMeta(date, locale = 'ru') {
const d = new Date(date);
const diff = Date.now() - d.getTime();
const str = format(d, locale);
return {
label: str,
isPast: diff > 0,
ageMs: Math.abs(diff),
ageHours: Math.abs(diff) / 3600000,
ageDays: Math.abs(diff) / 86400000,
};
}
/**
* Определяет "свежесть" даты.
*/
export function freshness(date) {
const ageMs = Date.now() - new Date(date).getTime();
if (ageMs < 60000) return 'just'; // < 1 мин
if (ageMs < 3600000) return 'fresh'; // < 1 ч
if (ageMs < 86400000) return 'recent'; // < 1 д
if (ageMs < 604800000) return 'old'; // < 1 нед
return 'ancient';
}
Обновлять таймеры только для видимых элементов:
import { render, cancel } from 'timeago.js';
function watchVisibility(nodes, locale = 'ru') {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
render(entry.target, locale);
} else {
cancel(entry.target);
}
});
});
nodes.forEach(node => observer.observe(node));
return {
destroy() {
nodes.forEach(node => {
observer.unobserve(node);
cancel(node);
});
observer.disconnect();
}
};
}
Пакетная инициализация с задержкой между элементами:
import { render } from 'timeago.js';
function batchRender(nodes, locale = 'ru', batchSize = 50) {
const arr = Array.from(nodes);
let i = 0;
function renderBatch() {
const batch = arr.slice(i, i + batchSize);
render(batch, locale);
i += batchSize;
if (i < arr.length) {
requestAnimationFrame(renderBatch);
}
}
requestAnimationFrame(renderBatch);
}
Ручное управление интервалами без render:
import { format } from 'timeago.js';
function createTimer(element, date, locale = 'ru') {
let timeoutId = null;
function getDelay() {
const diff = Math.abs(Date.now() - new Date(date).getTime());
if (diff < 60000) return 10000; // каждые 10с
if (diff < 3600000) return 60000; // каждую минуту
if (diff < 86400000) return 3600000; // каждый час
return 86400000;
}
function tick() {
element.textContent = format(date, locale);
timeoutId = setTimeout(tick, getDelay());
}
tick();
return { stop: () => clearTimeout(timeoutId) };
}
Форматирование всех элементов без автообновления:
import { format } from 'timeago.js';
function formatAll(selector = '[datetime]', locale = 'ru') {
document.querySelectorAll(selector).forEach(el => {
const date = el.getAttribute('datetime');
if (date) el.textContent = format(date, locale);
});
}
Декоратор для добавления дополнительной логики вокруг format:
import { format } from 'timeago.js';
function wrapFormat(beforeFn, afterFn) {
return function(date, locale = 'ru', opts) {
if (beforeFn) beforeFn(date, locale);
const result = format(date, locale, opts);
if (afterFn) return afterFn(result, date, locale);
return result;
};
}
const trackedFormat = wrapFormat(
(date) => analytics.track('timeago_format', { date }),
(result) => result
);