(function () {
var header = document.querySelector(".site-header");
var drawer = document.querySelector("[data-drawer]");
var openBtn = document.querySelector("[data-drawer-open]");
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 (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();
}
});
}
// 搜索表单:走路径 /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(); }); }); })();