(function () {
var HISTORY_KEY = "hgdj_search_history";
var HISTORY_MAX = 10;
var PLACEHOLDER_IMG = "/static/images/placeholder.png?v=2";
var input = document.querySelector("[data-mobile-search-input]");
var form = input && input.closest("form");
var clear = document.querySelector("[data-mobile-search-clear]");
var defaultView = document.querySelector("[data-search-default]");
var suggestions = document.querySelector("[data-search-suggestions]");
var suggestList = document.querySelector("[data-search-suggest-list]");
var history = document.querySelector("[data-search-history]");
var historyChips = document.querySelector("[data-history-chips]");
var historyClear = document.querySelector("[data-history-clear]");
if (!input || !form || !clear || !defaultView || !suggestions || !suggestList) return;
var suggestTimer = null;
var suggestSeq = 0;
function searchResultsPath(q) {
q = String(q || "").trim();
if (!q) return "/search";
return "/search/" + encodeURIComponent(q);
}
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 readHistory() {
try {
var raw = window.localStorage.getItem(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, HISTORY_MAX);
} catch (_) {
return [];
}
}
function writeHistory(list) {
try {
window.localStorage.setItem(HISTORY_KEY, JSON.stringify(list.slice(0, HISTORY_MAX)));
} catch (_) {
/* ignore quota / private mode */
}
}
function pushHistory(q) {
q = String(q || "").trim();
if (!q) return;
var list = readHistory().filter(function (item) {
return item !== q;
});
list.unshift(q);
writeHistory(list);
}
function clearHistory() {
try {
window.localStorage.removeItem(HISTORY_KEY);
} catch (_) {
/* ignore */
}
}
function renderHistory() {
if (!history || !historyChips) return;
var list = readHistory();
historyChips.innerHTML = "";
if (!list.length) {
history.hidden = true;
return;
}
history.hidden = false;
list.forEach(function (term) {
var link = document.createElement("a");
link.className = "mobile-search__chip";
link.href = searchResultsPath(term);
link.textContent = term;
historyChips.appendChild(link);
});
}
function renderSuggest(data, keyword) {
var html = "";
var feature = data && data.feature;
var items = (data && data.items) || [];
if (feature && feature.url) {
html +=
'' +
"" +
'
' +
highlightHTML(feature.title, keyword) +
"
" +
(feature.meta
? '"
: "") +
"播放' +
"
' +
'' +
highlightHTML(item.title || item.query || "", keyword) +
"" +
'' +
escapeHtml(item.kind || "") +
"" +
"";
});
if (!html) {
html =
'
暂无相关结果,可直接搜索“' + escapeHtml(keyword) + '”
'; } suggestList.innerHTML = html; if (typeof window.initLazyImages === "function") { window.initLazyImages(suggestList, { eager: true }); } } function fetchSuggest(keyword) { var q = String(keyword || "").trim(); if (!q) { suggestList.innerHTML = ""; return; } var seq = ++suggestSeq; suggestList.innerHTML = '搜索中…
'; 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 syncPanels() { var query = input.value.trim(); var hasQuery = query.length > 0; defaultView.hidden = hasQuery; suggestions.hidden = !hasQuery; clear.hidden = !hasQuery; if (!hasQuery) { suggestSeq += 1; suggestList.innerHTML = ""; } } function scheduleSuggest() { syncPanels(); var q = input.value.trim(); if (suggestTimer) clearTimeout(suggestTimer); if (!q) return; suggestTimer = setTimeout(function () { suggestTimer = null; fetchSuggest(q); }, 220); } input.addEventListener("input", scheduleSuggest); clear.addEventListener("click", function () { input.value = ""; input.dispatchEvent(new Event("input")); input.focus(); }); form.addEventListener("submit", function (event) { event.preventDefault(); var q = input.value.trim(); if (!q) { input.focus(); return; } pushHistory(q); window.location.href = searchResultsPath(q); }); if (historyClear && history) { historyClear.addEventListener("click", function () { clearHistory(); renderHistory(); }); } // 从联想 / 热搜跳转搜索结果时也写入本地历史 document.addEventListener("click", function (event) { var link = event.target.closest("a[data-suggest-query], a[href^='/search/']"); if (!link || link.hasAttribute("data-search-close")) return; var q = String(link.getAttribute("data-suggest-query") || "").trim(); if (!q) { var href = link.getAttribute("href") || ""; var match = href.match(/^\/search\/([^/?#]+)/); if (!match) return; try { q = decodeURIComponent(match[1]); } catch (_) { q = match[1]; } } if (q) pushHistory(q); }); document.querySelectorAll("[data-search-close]").forEach(function (link) { link.addEventListener("click", function (event) { if (!document.referrer) return; try { if (new URL(document.referrer).origin === window.location.origin) { event.preventDefault(); window.history.back(); } } catch (_) { /* Use the link destination when the referrer cannot be read. */ } }); }); renderHistory(); syncPanels(); if (input.value.trim()) { fetchSuggest(input.value.trim()); } })();