Shikimori — Комментарии
HTML
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<header><div class="logo">shiki<span>comments</span></div></header>
<div id="id-section">
<label>Topic ID — ID темы на Shikimori</label>
<div class="row">
<input type="number" id="tid" placeholder="например: 3238" min="1">
<button class="btn" id="go-btn">Показать</button>
</div>
</div>
<div id="comm-section">
<div class="topbar">
<button class="back-btn" id="back-btn">← Сменить ID</button>
<span class="count-lbl" id="cnt"></span>
</div>
<div class="box">
<div class="box-head">
<span>Комментарии</span>
<span class="tid" id="tid-lbl"></span>
</div>
<div id="lm-row">
<button class="lm-btn" id="lm-btn">⬆ Загрузить ещё (более старые)</button>
</div>
<div id="clist"></div>
</div>
</div>
<div id="dbg"></div>
CSS
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0f1117; --surface: #181c27; --surface2: #1e2435;
--border: #2a3050; --accent: #2e86de;
--text: #dce4f0; --muted: #6b7a99; --link: #5ba4f5;
--r: 10px;
}
body {
background: var(--bg); color: var(--text);
font-family: 'Nunito', sans-serif;
min-height: 100vh; display: flex; flex-direction: column;
align-items: center; padding: 36px 16px 60px;
}
header { width: 100%; max-width: 720px; margin-bottom: 24px; }
.logo { font-size: 20px; font-weight: 800; }
.logo span { color: var(--accent); }
#id-section {
width: 100%; max-width: 720px;
background: var(--surface); border: 1px solid var(--border);
border-radius: var(--r); padding: 22px 22px 20px;
margin-bottom: 20px;
}
#id-section label {
display: block; font-size: 11px; font-weight: 700;
text-transform: uppercase; letter-spacing: .08em;
color: var(--muted); margin-bottom: 10px;
}
.row { display: flex; gap: 8px; }
input[type=number] {
flex: 1; background: var(--bg); border: 1.5px solid var(--border);
border-radius: 7px; color: var(--text);
font-family: 'JetBrains Mono', monospace; font-size: 15px;
padding: 10px 14px; outline: none; transition: border-color .2s;
-moz-appearance: textfield;
}
input[type=number]::-webkit-inner-spin-button { display: none; }
input[type=number]:focus { border-color: var(--accent); }
input[type=number].err { border-color: #f06292; }
.btn {
background: var(--accent); color: #fff; border: none;
border-radius: 7px; font-family: 'Nunito', sans-serif;
font-weight: 700; font-size: 14px; padding: 10px 20px;
cursor: pointer; white-space: nowrap;
transition: background .15s, transform .1s;
}
.btn:hover { background: #1a6fc4; }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .45; pointer-events: none; }
...
JavaScript
const BASE = 'https://shikimori.one';
const LIMIT = 30;
let topicId = null;
let totalLoaded = 0;
let oldPage = 2;
let noMore = false;
const idSec = document.getElementById('id-section');
const commSec = document.getElementById('comm-section');
const tidInp = document.getElementById('tid');
const goBtn = document.getElementById('go-btn');
const backBtn = document.getElementById('back-btn');
const cntEl = document.getElementById('cnt');
const tidLbl = document.getElementById('tid-lbl');
const lmRow = document.getElementById('lm-row');
const lmBtn = document.getElementById('lm-btn');
const clist = document.getElementById('clist');
const dbg = document.getElementById('dbg');
function log(s) {
dbg.style.display = 'block';
dbg.textContent += s + '\n';
}
function ago(d) {
const s = Math.floor((Date.now() - new Date(d)) / 1000);
if (s < 5) return 'только что';
if (s < 20) return 'несколько секунд назад';
if (s < 90) return 'минуту назад';
if (s < 150) return '2 минуты назад';
if (s < 270) return '4 минуты назад';
if (s < 600) return `${Math.round(s/60)} минут назад`;
if (s < 2100) return 'полчаса назад';
if (s < 3600) return `${Math.round(s/60)} минут назад`;
if (s < 5400) return 'час назад';
if (s < 7200) return 'полтора часа назад';
if (s < 10800) return '2 часа назад';
if (s < 86400) return `${Math.round(s/3600)} часов назад`;
if (s < 130000) return 'вчера';
if (s < 220000) return '2 дня назад';
if (s < 310000) return '3 дня назад';
if (s < 530000) return '4 дня назад';
if (s < 700000) return 'неделю назад';
if (s < 1300000) return 'полторы недели назад';
if (s < 1900000) return '2 недели назад';
if (s < 2500000) return '3 недели назад';
if (s < 4000000) return 'месяц назад';
if (s < 8000000) return 'несколько месяцев назад';
if (s < 16000000) return 'полгода назад';
const y = Math.round(s/31536000);
if (y === 1) return 'год...