(function () {
var header = document.querySelector(".site-header");
var drawer = document.querySelector("[data-drawer]");
var openBtn = document.querySelector("[data-drawer-open]");
var userMenu = document.querySelector("[data-user-menu]");
if (header) {
var threshold = 48;
var ticking = false;
function measure() {
document.documentElement.style.setProperty("--site-header-height", header.getBoundingClientRect().height + "px");
}
function update() {
ticking = false;
header.classList.toggle("is-scrolled", window.scrollY > threshold);
}
function onScroll() {
if (ticking) return;
ticking = true;
window.requestAnimationFrame(update);
}
measure();
update();
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", measure);
if ("ResizeObserver" in window) new ResizeObserver(measure).observe(header);
}
// 用户下拉菜单
if (userMenu) {
var toggle = userMenu.querySelector("[data-user-menu-toggle]");
function openUserMenu() {
userMenu.classList.add("is-open");
if (toggle) toggle.setAttribute("aria-expanded", "true");
}
function closeUserMenu() {
userMenu.classList.remove("is-open");
if (toggle) toggle.setAttribute("aria-expanded", "false");
}
function toggleUserMenu(e) {
e.stopPropagation();
if (userMenu.classList.contains("is-open")) {
closeUserMenu();
} else {
openUserMenu();
}
}
if (toggle) {
toggle.addEventListener("click", toggleUserMenu);
}
document.addEventListener("click", function (e) {
if (!userMenu.contains(e.target)) {
closeUserMenu();
}
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeUserMenu();
});
}
// 左侧抽屉
if (drawer && openBtn) {
var closeEls = drawer.querySelectorAll("[data-drawer-close]");
function openDrawer() {
drawer.classList.add("is-open");
document.body.classList.add("drawer-open");
openBtn.setAttribute("aria-expanded", "true");
}
function closeDrawer() {
drawer.classList.remove("is-open");
document.body.classList.remove("drawer-open");
openBtn.setAttribute("aria-expanded", "false");
}
openBtn.setAttribute("aria-expanded", "false");
openBtn.setAttribute("aria-controls", "site-drawer");
openBtn.addEventListener("click", openDrawer);
closeEls.forEach(function (el) {
el.addEventListener("click", closeDrawer);
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && drawer.classList.contains("is-open")) {
closeDrawer();
}
});
}
function openAccountSwitch(event) {
if (event) event.preventDefault();
if (userMenu) {
userMenu.classList.remove("is-open");
var userToggle = userMenu.querySelector("[data-user-menu-toggle]");
if (userToggle) userToggle.setAttribute("aria-expanded", "false");
}
if (drawer) {
drawer.classList.remove("is-open");
document.body.classList.remove("drawer-open");
if (openBtn) openBtn.setAttribute("aria-expanded", "false");
}
if (typeof window.openAccountSwitchLogin === "function") {
window.openAccountSwitchLogin();
return;
}
if (typeof window.openLoginPop === "function") {
window.openLoginPop();
return;
}
window.location.href = "/login";
}
document.querySelectorAll("[data-account-switch]").forEach(function (btn) {
btn.addEventListener("click", openAccountSwitch);
});
// 搜索表单:走路径 /search/{q},不用 query;同时写入本地搜索历史
var SEARCH_HISTORY_KEY = "hgdj_search_history";
var SEARCH_HISTORY_MAX = 10;
function searchResultsPath(q) {
q = String(q || "").trim();
if (!q) return "/search";
return "/search/" + encodeURIComponent(q).replace(/%20/g, "%20");
}
function readSearchHistory() {
try {
var raw = window.localStorage.getItem(SEARCH_HISTORY_KEY);
var list = raw ? JSON.parse(raw) : [];
if (!Array.isArray(list)) return [];
return list
.map(function (item) {
return String(item || "").trim();
})
.filter(Boolean)
.slice(0, SEARCH_HISTORY_MAX);
} catch (_) {
return [];
}
}
function writeSearchHistory(list) {
try {
window.localStorage.setItem(
SEARCH_HISTORY_KEY,
JSON.stringify(list.slice(0, SEARCH_HISTORY_MAX))
);
} catch (_) {
/* ignore quota / private mode */
}
}
function pushSearchHistory(q) {
q = String(q || "").trim();
if (!q) return;
var list = readSearchHistory().filter(function (item) {
return item !== q;
});
list.unshift(q);
writeSearchHistory(list);
}
function clearSearchHistory() {
try {
window.localStorage.removeItem(SEARCH_HISTORY_KEY);
} catch (_) {
/* ignore */
}
}
document.querySelectorAll("form[data-path-search]").forEach(function (form) {
form.addEventListener("submit", function (event) {
event.preventDefault();
var input = form.querySelector('input[type="search"], input[name="q"]');
var q = input ? String(input.value || "").trim() : "";
if (!q) {
if (input) input.focus();
return;
}
pushSearchHistory(q);
window.location.href = searchResultsPath(q);
});
var input = form.querySelector("[data-header-search-input], input[type='search'], input[name='q']");
var clear = form.querySelector("[data-header-search-clear]");
if (input && clear) {
function syncClear() {
clear.hidden = !String(input.value || "").trim();
}
input.addEventListener("input", syncClear);
clear.addEventListener("click", function () {
input.value = "";
syncClear();
input.dispatchEvent(new Event("input", { bubbles: true }));
input.focus();
});
syncClear();
}
// PC header 搜索下拉:聚焦展开历史 + 热搜;输入时切换联想
var dropdown = form.querySelector("[data-header-search-dropdown]");
if (!dropdown || !input) return;
var historyBox = form.querySelector("[data-header-search-history]");
var historyChips = form.querySelector("[data-header-history-chips]");
var historyClear = form.querySelector("[data-header-history-clear]");
var idleBox = form.querySelector("[data-header-search-idle]");
var suggestBox = form.querySelector("[data-header-search-suggest]");
var closeTimer = null;
var suggestTimer = null;
var suggestSeq = 0;
var PLACEHOLDER_IMG = "/static/images/placeholder.png?v=2";
function escapeHtml(text) {
return String(text || "")
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """);
}
function highlightHTML(text, keyword) {
var raw = String(text || "");
var key = String(keyword || "").trim();
if (!raw) return "";
if (!key) return escapeHtml(raw);
var lowerRaw = raw.toLowerCase();
var lowerKey = key.toLowerCase();
var idx = lowerRaw.indexOf(lowerKey);
if (idx < 0) return escapeHtml(raw);
var before = raw.slice(0, idx);
var hit = raw.slice(idx, idx + key.length);
var after = raw.slice(idx + key.length);
return (
escapeHtml(before) +
'' +
escapeHtml(hit) +
"" +
escapeHtml(after)
);
}
function renderHistory() {
if (!historyBox || !historyChips) return;
var list = readSearchHistory();
historyChips.innerHTML = "";
if (!list.length) {
historyBox.hidden = true;
return;
}
historyBox.hidden = false;
list.forEach(function (term) {
var link = document.createElement("a");
link.className = "search-dropdown__chip";
link.href = searchResultsPath(term);
link.textContent = term;
historyChips.appendChild(link);
});
}
function showIdlePanel() {
if (idleBox) idleBox.hidden = false;
if (suggestBox) {
suggestBox.hidden = true;
suggestBox.innerHTML = "";
}
}
function showSuggestPanel() {
if (idleBox) idleBox.hidden = true;
if (suggestBox) suggestBox.hidden = false;
}
function renderSuggest(data, keyword) {
if (!suggestBox) return;
var html = "";
var feature = data && data.feature;
var items = (data && data.items) || [];
if (feature && feature.url) {
html +=
'' +
"" +
'
' +
highlightHTML(feature.title, keyword) +
"
" +
(feature.meta
? '"
: "") +
"播放' +
"
暂无相关结果,回车搜索“' + escapeHtml(keyword) + '”
'; } suggestBox.innerHTML = html; showSuggestPanel(); if (typeof window.initLazyImages === "function") { window.initLazyImages(suggestBox, { eager: true }); } } function fetchSuggest(keyword) { var q = String(keyword || "").trim(); if (!q || !suggestBox) { showIdlePanel(); openDropdown(); return; } var seq = ++suggestSeq; showSuggestPanel(); suggestBox.innerHTML = '搜索中…
'; openDropdown(); var req; if (window.HttpRequest && typeof window.HttpRequest.get === "function") { req = window.HttpRequest.get("/api/web/search/suggest", { params: { keyword: q }, }); } else { req = fetch( "/api/web/search/suggest?keyword=" + encodeURIComponent(q), { credentials: "include", headers: { Accept: "application/json" } } ).then(function (res) { return res.json(); }); } Promise.resolve(req) .then(function (data) { if (seq !== suggestSeq) return; renderSuggest(data || {}, q); }) .catch(function () { if (seq !== suggestSeq) return; renderSuggest( { feature: null, items: [ { title: q, kind: "搜索", query: q, url: searchResultsPath(q), }, ], }, q ); }); } function scheduleSuggest() { var q = String(input.value || "").trim(); if (suggestTimer) clearTimeout(suggestTimer); if (!q) { suggestSeq += 1; showIdlePanel(); openDropdown(); return; } suggestTimer = setTimeout(function () { suggestTimer = null; fetchSuggest(q); }, 220); } function openDropdown() { if (closeTimer) { clearTimeout(closeTimer); closeTimer = null; } var q = String(input.value || "").trim(); if (q) { if (suggestBox && suggestBox.hidden) { scheduleSuggest(); } dropdown.hidden = false; form.classList.add("is-open"); input.setAttribute("aria-expanded", "true"); return; } showIdlePanel(); renderHistory(); var hasHistory = historyBox && !historyBox.hidden; var hasHot = !!(idleBox && idleBox.querySelector(".search-dropdown__hot")); if (!hasHistory && !hasHot) { dropdown.hidden = true; form.classList.remove("is-open"); input.setAttribute("aria-expanded", "false"); return; } dropdown.hidden = false; form.classList.add("is-open"); input.setAttribute("aria-expanded", "true"); } function closeDropdown() { dropdown.hidden = true; form.classList.remove("is-open"); input.setAttribute("aria-expanded", "false"); } function scheduleClose() { if (closeTimer) clearTimeout(closeTimer); closeTimer = setTimeout(function () { closeTimer = null; if (!form.contains(document.activeElement)) { closeDropdown(); } }, 120); } input.addEventListener("focus", openDropdown); input.addEventListener("click", openDropdown); input.addEventListener("input", function () { if (clear) clear.hidden = !String(input.value || "").trim(); scheduleSuggest(); }); input.addEventListener("blur", scheduleClose); dropdown.addEventListener("mousedown", function (event) { // 点击下拉内链接/按钮时先阻止 input blur 抢先关闭 event.preventDefault(); }); dropdown.addEventListener("click", function (event) { var chip = event.target.closest ? event.target.closest( ".search-dropdown__chip, .search-dropdown__link, .search-dropdown__feature-play, .search-dropdown__feature-cover, .search-dropdown__suggest-item" ) : null; if (chip && chip.href) { var q = ""; if (chip.classList.contains("search-dropdown__chip")) { q = String(chip.textContent || "").trim(); } else if (chip.classList.contains("search-dropdown__link")) { var name = chip.querySelector(".search-dropdown__name"); if (name) q = String(name.textContent || "").trim(); } else if (chip.getAttribute("data-suggest-query")) { q = String(chip.getAttribute("data-suggest-query") || "").trim(); } else { q = String(input.value || "").trim(); } if (q) pushSearchHistory(q); window.location.href = chip.href; } }); if (historyClear) { historyClear.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); clearSearchHistory(); renderHistory(); openDropdown(); input.focus(); }); } document.addEventListener("keydown", function (event) { if (event.key === "Escape" && !dropdown.hidden) { closeDropdown(); input.blur(); } }); document.addEventListener("mousedown", function (event) { if (dropdown.hidden) return; if (form.contains(event.target)) return; closeDropdown(); }); }); var PLACEHOLDER = "/static/images/placeholder.png?v=2"; var DEFAULT_AVATAR = "/static/images/profile/avatar.png"; function usableAvatar(url) { var u = String(url || "").trim(); if (!u) return ""; if (/^https?:\/\//i.test(u) || u.indexOf("/static/") === 0) return u; return ""; } function setAvatarImg(img, url) { if (!img) return; var src = usableAvatar(url); img.removeAttribute("data-decrypted"); img.removeAttribute("data-decrypt-failed"); if (src && typeof window.shouldDecryptImage === "function" && window.shouldDecryptImage(src)) { img.classList.add("lazy"); img.src = PLACEHOLDER; img.setAttribute("data-src", src); img.setAttribute("data-lazy-eager", "1"); } else { img.classList.remove("lazy"); img.removeAttribute("data-src"); img.removeAttribute("data-lazy-eager"); img.src = src || DEFAULT_AVATAR; } } function refreshAvatarDecrypt(root) { var scope = root || document; if (typeof window.initLazyImages === "function") { window.initLazyImages(scope, { eager: true }); return; } if (typeof window.loadLazyNode !== "function") return; scope .querySelectorAll( "img.user-chip__avatar.lazy[data-src], img.user-menu__avatar.lazy[data-src], img.drawer__avatar.lazy[data-src], img.play-composer__avatar-img.lazy[data-src]" ) .forEach(function (img) { window.loadLazyNode(img); }); } function formatRecharge(raw) { var n = Math.floor(Number(raw)); if (!isFinite(n) || n < 0) n = 0; var s = String(n); if (s.length <= 3) return s; var out = []; var rem = s.length % 3; if (rem) out.push(s.slice(0, rem)); for (var i = rem; i < s.length; i += 3) out.push(s.slice(i, i + 3)); return out.join(","); } function syncHeaderUser() { var session = window.CookieUtil && typeof CookieUtil.getAuthSession === "function" ? CookieUtil.getAuthSession() : null; if (!session) return; var avatar = usableAvatar(session.avatar); document.querySelectorAll("[data-header-avatar]").forEach(function (img) { if (avatar) setAvatarImg(img, avatar); }); var name = String(session.nickName || session.accountNo || "").trim(); if (name) { document.querySelectorAll(".user-chip__name, .user-menu__meta strong, .drawer__meta strong").forEach(function (el) { el.textContent = name; }); } if (session.userId) { document.querySelectorAll(".user-menu__meta span, .drawer__meta span").forEach(function (el) { if (/^ID\b/.test(String(el.textContent || "").trim())) { el.textContent = "ID " + session.userId; } }); } if (Object.prototype.hasOwnProperty.call(session, "recharge") && session.recharge !== "") { var text = formatRecharge(session.recharge); document.querySelectorAll("[data-header-recharge]").forEach(function (el) { el.textContent = text; }); } refreshAvatarDecrypt(document); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", syncHeaderUser); } else { syncHeaderUser(); } document.addEventListener("auth:login", syncHeaderUser); document.addEventListener("auth:logout", syncHeaderUser); window.refreshAvatarDecrypt = refreshAvatarDecrypt; window.setAvatarImg = setAvatarImg; window.syncHeaderUser = syncHeaderUser; })();