mirror of
https://github.com/Vb-Lg/class-history-template.git
synced 2026-11-03 21:06:40 +00:00
61 lines
2.2 KiB
JavaScript
61 lines
2.2 KiB
JavaScript
/* ================= 歌单每日随机排序 ================= */
|
|
/* 顺序只由「日期」决定:同一天所有访客看到的顺序完全一致,
|
|
北京时间每天 0 点自动换一套(无需重新构建,静态页面也能生效)。 */
|
|
(function () {
|
|
const list = document.querySelector('.song-list');
|
|
if (!list) return;
|
|
|
|
const items = Array.from(list.children).filter((el) =>
|
|
el.classList && el.classList.contains('song')
|
|
);
|
|
if (items.length < 2) return;
|
|
|
|
// 北京时间(UTC+8)当天,如 2026-10-06
|
|
const day = new Date(Date.now() + 8 * 60 * 60 * 1000)
|
|
.toISOString()
|
|
.slice(0, 10);
|
|
|
|
// FNV-1a:把日期压成 32 位种子
|
|
let seed = 0x811c9dc5;
|
|
for (let i = 0; i < day.length; i++) {
|
|
seed ^= day.charCodeAt(i);
|
|
seed = Math.imul(seed, 0x01000193) >>> 0;
|
|
}
|
|
|
|
// mulberry32:同一种子 → 同一串伪随机数(跨浏览器一致)
|
|
function rand() {
|
|
seed = (seed + 0x6d2b79f5) >>> 0;
|
|
let t = seed;
|
|
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
}
|
|
|
|
// Fisher–Yates 洗牌(固定种子,结果可复现)
|
|
for (let i = items.length - 1; i > 0; i--) {
|
|
const j = Math.floor(rand() * (i + 1));
|
|
const tmp = items[i];
|
|
items[i] = items[j];
|
|
items[j] = tmp;
|
|
}
|
|
|
|
// 按新顺序放回,并重排序号。
|
|
// 注意:这里不要写 transition-delay。入场错峰统一由 pages.js 在元素
|
|
// 进入视口时按「当前文档顺序」计算;两处各写一套延时就会互相错开。
|
|
const frag = document.createDocumentFragment();
|
|
items.forEach((el, i) => {
|
|
const no = el.querySelector('.no');
|
|
if (no) no.textContent = String(i + 1).padStart(2, '0');
|
|
frag.appendChild(el);
|
|
});
|
|
list.appendChild(frag);
|
|
|
|
// 提示条上标注当前生效的日期
|
|
const tip = document.getElementById('shuffle-tip');
|
|
const dayEl = document.getElementById('shuffle-day');
|
|
if (tip && dayEl) {
|
|
dayEl.textContent = day;
|
|
tip.hidden = false;
|
|
}
|
|
})();
|