您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Показывает секунды первую минуту. Обновляет значение каждую секунду. До 1 часа считает время и также каждую минуту обновляет значение без обновления страницы. Воркает на устройстве (нагрузка).
当前为
// ==UserScript== // @name Lolz.live Dynamic Time // @namespace http://tampermonkey.net/ // @version 1.1 // @description Показывает секунды первую минуту. Обновляет значение каждую секунду. До 1 часа считает время и также каждую минуту обновляет значение без обновления страницы. Воркает на устройстве (нагрузка). // @author eretly // @match https://lolz.live/* // @match https://lzt.market/* // @grant none // ==/UserScript== (function () { 'use strict'; const activeElements = new WeakMap(); let updateTimer = null; function pluralize(number, one, few, many) { number = Math.abs(number); if (number % 100 >= 11 && number % 100 <= 19) return many; switch (number % 10) { case 1: return one; case 2: case 3: case 4: return few; default: return many; } } function getSafeDiff(timestamp) { return Math.max(0, Math.floor(Date.now() / 1000) - timestamp); } function formatRelativeTime(diff) { diff = Math.max(0, diff); if (diff < 60) { return `${diff} ${pluralize(diff, 'секунду', 'секунды', 'секунд')} назад`; } else if (diff < 120) { return 'Минуту назад'; } else if (diff < 3600) { const mins = Math.floor(diff / 60); return `${mins} мин. назад`; } return null; } function formatAbsoluteTime(el) { const timeStr = el.getAttribute('data-timestring'); if (!timeStr) return null; return `Сегодня, в ${timeStr}`; } function updateTimes() { const now = Math.floor(Date.now() / 1000); let needsUpdate = false; document.querySelectorAll('abbr.DateTime[data-time]').forEach(el => { const currentText = el.textContent; if (/сегодня|вчера|\d{1,2} \w+ \d{4}/i.test(currentText)) return; const timestamp = parseInt(el.getAttribute('data-time')); const diff = getSafeDiff(timestamp); if (diff < 3600) { if (!el.hasAttribute('data-original-text')) { el.setAttribute('data-original-text', currentText); } const newText = formatRelativeTime(diff); if (newText && el.textContent !== newText) { el.textContent = newText; } activeElements.set(el, true); needsUpdate = true; } else if (activeElements.has(el)) { const absText = formatAbsoluteTime(el); if (absText) el.textContent = absText; activeElements.delete(el); } }); if (needsUpdate && !updateTimer) { updateTimer = setTimeout(() => { updateTimer = null; updateTimes(); }, 1000); } else if (!needsUpdate && updateTimer) { clearTimeout(updateTimer); updateTimer = null; } } const observer = new MutationObserver(mutations => { let shouldUpdate = false; mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const timeNodes = node.matches('abbr.DateTime[data-time]') ? [node] : Array.from(node.querySelectorAll('abbr.DateTime[data-time]')); timeNodes.forEach(el => { const currentText = el.textContent; if (/сегодня|вчера|\d{1,2} \w+ \d{4}/i.test(currentText)) return; const timestamp = parseInt(el.getAttribute('data-time')); const diff = getSafeDiff(timestamp); if (diff < 3600) { el.setAttribute('data-original-text', el.textContent); const newText = formatRelativeTime(diff); if (newText) el.textContent = newText; activeElements.set(el, true); shouldUpdate = true; } else { const absText = formatAbsoluteTime(el); if (absText) el.textContent = absText; } }); } }); }); if (shouldUpdate) { setTimeout(updateTimes, 50); } }); function init() { document.querySelectorAll('abbr.DateTime[data-time]').forEach(el => { const currentText = el.textContent; if (/сегодня|вчера|\d{1,2} \w+ \d{4}/i.test(currentText)) return; const timestamp = parseInt(el.getAttribute('data-time')); const diff = getSafeDiff(timestamp); if (diff < 3600) { el.setAttribute('data-original-text', el.textContent); const newText = formatRelativeTime(diff); if (newText) el.textContent = newText; activeElements.set(el, true); } else { const absText = formatAbsoluteTime(el); if (absText) el.textContent = absText; } }); updateTimes(); observer.observe(document.body, { childList: true, subtree: true }); ['click', 'scroll', 'mousemove'].forEach(event => { document.addEventListener(event, () => { setTimeout(updateTimes, 100); }, { passive: true }); }); } if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } window.addEventListener('unload', () => { observer.disconnect(); if (updateTimer) clearTimeout(updateTimer); }); })();