feat(navigation): hard-switch to Zibll navigation and Font Awesome 5

This commit is contained in:
kate522 committed 2026-08-18 20:46:21 +08:00
1 parent 3c3ddac8be
commit a0b84977a2
630 files changed
+101647 -11293

No files matched your search

+2 -2
View File
@@ -180,14 +180,14 @@
btn.dataset.initialActive = isActive ? "1" : "0";
btn.classList.toggle("is-active", isActive);
var icon = btn.querySelector("i");
if (icon) icon.className = isActive ? "fas fa-heart" : "far fa-heart";
if (icon) icon.className = isActive ? "fa fas fa-heart" : "fa fas fa-heart";
}
function paintFavorite(btn, isActive) {
btn.dataset.initialActive = isActive ? "1" : "0";
btn.classList.toggle("is-active", isActive);
var icon = btn.querySelector("i");
if (icon) icon.className = isActive ? "fas fa-star" : "far fa-star";
if (icon) icon.className = isActive ? "fa fas fa-star" : "fa fas fa-star";
}
function applyLikeState(isActive, count) {
+2 -2
View File
@@ -35,7 +35,7 @@
submitBtn.classList.add("is-loading");
submitBtn.disabled = true;
var loadingText = (window.aksrtData && aksrtData.commentSubmittingText) || '发送中...';
setSubmitBtnContent('<i class="fas fa-circle-notch fa-spin"></i> ' + loadingText, loadingText);
setSubmitBtnContent('<i class="fa fas fa-spinner fa-spin"></i> ' + loadingText, loadingText);
} else {
isSubmitting = false;
submitBtn.classList.remove("is-loading");
@@ -81,7 +81,7 @@
countdownTimer = setInterval(function () {
setSubmitBtnContent(
'<i class="fas fa-clock"></i> 请等待 ' + remaining + 's',
'<i class="fa fas fa-clock"></i> 请等待 ' + remaining + 's',
'请等待 ' + remaining + 's'
);
-57
View File
@@ -1,57 +0,0 @@
/**
* AKSRT Dropdown Menus — post-meta only.
* Header user box uses CSS hover (.navbar-top .sub-menu) per zibll contract.
*/
(function () {
"use strict";
function initPostDropMeta() {
document.querySelectorAll('.post-drop-meta').forEach(function (wrap) {
if (!wrap || wrap.dataset.aksrtDropMetaBound === '1') return;
var trigger = wrap.querySelector('.post-drop-meta__toggle');
var menu = wrap.querySelector('.post-drop-meta__menu');
if (!trigger || !menu) return;
wrap.dataset.aksrtDropMetaBound = '1';
function close() {
wrap.classList.remove('is-open');
trigger.setAttribute('aria-expanded', 'false');
menu.setAttribute('aria-hidden', 'true');
}
trigger.addEventListener('click', function (e) {
e.stopPropagation();
var open = !wrap.classList.contains('is-open');
document.querySelectorAll('.post-drop-meta.is-open').forEach(function (other) {
if (other !== wrap) {
other.classList.remove('is-open');
var t = other.querySelector('.post-drop-meta__toggle');
var m = other.querySelector('.post-drop-meta__menu');
if (t) t.setAttribute('aria-expanded', 'false');
if (m) m.setAttribute('aria-hidden', 'true');
}
});
wrap.classList.toggle('is-open', open);
trigger.setAttribute('aria-expanded', open ? 'true' : 'false');
menu.setAttribute('aria-hidden', open ? 'false' : 'true');
});
document.addEventListener('click', function (e) {
if (!wrap.contains(e.target)) close();
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') close();
});
});
}
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
window.AksrtFrontend.register('aksrt-post-drop-meta', function () {
initPostDropMeta();
});
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initPostDropMeta);
} else {
initPostDropMeta();
}
})();
-31
View File
@@ -47,19 +47,6 @@
function initPostThumbMedia(root) {
var scope = root || document;
scope.querySelectorAll("[data-post-thumb-slider]").forEach(function (el) {
if (el.dataset.aksrtThumbSliderBound === "1" || typeof Swiper === "undefined") return;
el.dataset.aksrtThumbSliderBound = "1";
new Swiper(el, {
slidesPerView: 1,
loop: el.querySelectorAll(".swiper-slide").length > 1,
pagination: {
el: el.querySelector(".swiper-pagination"),
clickable: true,
},
});
});
scope.querySelectorAll("[data-post-thumb-video]").forEach(function (box) {
if (box.dataset.aksrtThumbVideoBound === "1") return;
box.dataset.aksrtThumbVideoBound = "1";
@@ -100,24 +87,6 @@
initGradientBackgrounds(root);
});
function initRelatedSwiper() {
var el = document.querySelector(".related-swiper[data-swiper-config]");
if (!el || typeof Swiper === "undefined") return;
var config = {};
try { config = JSON.parse(el.dataset.swiperConfig || "{}"); } catch (e) {}
new Swiper(el, Object.assign({
slidesPerView: "auto",
spaceBetween: 12,
freeMode: true,
navigation: {
nextEl: ".related-swiper-next",
prevEl: ".related-swiper-prev",
},
}, config));
}
window.AksrtFrontend.register("aksrt-related-swiper", function () { initRelatedSwiper(); });
})();
(function () {
-144
View File
@@ -1,144 +0,0 @@
/**
* AKSRT nav chrome — zibll contract (folding, chevron, language, drawer a11y).
* Drawer open/close via aksrt-runtime [data-toggle-class] → body.mobile-navbar-show.
*/
(function () {
"use strict";
var foldTimer = null;
function appendChevrons(root) {
(root || document).querySelectorAll(".navbar-top li.menu-item-has-children > a").forEach(function (a) {
if (a.querySelector(".fa-angle-down, .fas.fa-angle-down")) return;
var i = document.createElement("i");
i.className = "fa fa-angle-down ml6";
i.setAttribute("aria-hidden", "true");
a.appendChild(i);
});
}
function clearFolding() {
// Support both zibll-style more and any legacy .aksrt-nav-more nodes.
var mores = document.querySelectorAll(".navbar-nav > li.aksrt-nav-more");
Array.prototype.forEach.call(mores, function (more) {
var nav = more.parentNode;
if (!nav) {
more.remove();
return;
}
// Prefer direct child .sub-menu (zibll contract); fall back to first matching submenu.
var sub = null;
for (var i = 0; i < more.children.length; i++) {
var child = more.children[i];
if (
child.tagName === "UL" &&
(child.classList.contains("sub-menu") ||
child.classList.contains("aksrt-nav-more__dropdown"))
) {
sub = child;
break;
}
}
if (!sub) {
sub = more.querySelector(".sub-menu, .aksrt-nav-more__dropdown");
}
if (sub) {
while (sub.firstChild) {
// Guard: only insertBefore when more is still a child of nav.
if (more.parentNode === nav) {
nav.insertBefore(sub.firstChild, more);
} else {
nav.appendChild(sub.firstChild);
}
}
}
more.remove();
});
}
function navFolding() {
var collapse = document.querySelector(".navbar-collapse");
var nav = document.querySelector(".navbar-nav");
if (!collapse || !nav) return;
clearFolding();
if (window.innerWidth <= 996) return;
var header = document.querySelector(".header");
if (header && header.offsetHeight <= 81) return;
var surplus = collapse.clientWidth;
Array.prototype.forEach.call(collapse.children, function (child) {
if (!child.classList.contains("navbar-nav")) {
surplus -= child.offsetWidth || 0;
}
});
var headerEl = document.querySelector(".navbar-header");
surplus -= (headerEl ? headerEl.offsetWidth : 0) + 40;
var navsWidth = 66;
var foldItems = [];
Array.prototype.forEach.call(nav.children, function (li) {
if (li.classList.contains("aksrt-nav-more")) return;
navsWidth += li.offsetWidth || 0;
if (navsWidth > surplus) foldItems.push(li);
});
if (!foldItems.length) return;
var more = document.createElement("li");
more.className = "menu-item menu-item-has-children aksrt-nav-more";
more.innerHTML =
'<a href="javascript:void(0);"><i class="fas fa-bars" aria-hidden="true"></i></a><ul class="sub-menu"></ul>';
var sub = more.querySelector(".sub-menu");
foldItems.forEach(function (li) {
if (li && li.parentNode) sub.appendChild(li);
});
nav.appendChild(more);
appendChevrons(more);
}
function scheduleFold() {
if (foldTimer) clearTimeout(foldTimer);
foldTimer = setTimeout(function () {
try { navFolding(); } catch (e) {}
}, 80);
}
function bindLanguage() {
document.addEventListener("click", function (e) {
var btn = e.target && e.target.closest ? e.target.closest(".translate-button[data-language]") : null;
if (!btn) return;
e.preventDefault();
var lang = btn.getAttribute("data-language");
if (!lang) return;
try { localStorage.setItem("aksrt_lang", lang); } catch (err) {}
var url = new URL(window.location.href);
url.searchParams.set("lang", lang);
window.location.href = url.toString();
});
}
function bindDrawerA11y() {
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && document.body.classList.contains("mobile-navbar-show")) {
document.body.classList.remove("mobile-navbar-show");
}
});
}
function init() {
appendChevrons();
scheduleFold();
bindLanguage();
bindDrawerA11y();
window.addEventListener("resize", scheduleFold, { passive: true });
}
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
window.AksrtFrontend.register("aksrt-nav-chrome", function () { init(); });
} else if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
-168
View File
@@ -1,168 +0,0 @@
/**
* AKSRT Scroll Behaviors — back-to-top, floating buttons, reading progress, nav scroll
*/
(function () {
"use strict";
function initBackToTop() {
var el = document.getElementById("float-back-to-top") || document.getElementById("back-to-top");
if (!el) return;
function onScroll() {
if (window.scrollY > 400) {
el.classList.add("is-visible");
} else {
el.classList.remove("is-visible");
}
}
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
el.addEventListener("click", function (e) {
e.preventDefault();
if (window.aksrt && aksrt.scrollTopTo) {
aksrt.scrollTopTo(0);
} else {
window.scrollTo({ top: 0, behavior: "smooth" });
}
});
}
function initFloatingButtons() {
var wrap = document.getElementById("float-right-btns");
if (!wrap) return;
function debugEnabled() {
return !!(window.aksrtData && aksrtData.debug);
}
function debugLog(message, context, level) {
if (!debugEnabled()) return;
var method = level === "error" ? "error" : (level === "warn" ? "warn" : "log");
console[method]("[AKSRT FloatingButtons] " + message, context || {});
}
function reportDebug(eventName, payload) {
if (!(window.aksrtData && aksrtData.debugLog && aksrtData.ajaxUrl && aksrtData.nonce)) {
return;
}
var body = new URLSearchParams();
body.set("action", "aksrt_frontend_debug");
body.set("nonce", aksrtData.nonce);
body.set("source", "floating_buttons");
body.set("event", eventName);
body.set("page", window.location.href);
if (payload && payload.text) body.set("text", String(payload.text));
if (payload && payload.size) body.set("size", String(payload.size));
if (payload && payload.error) body.set("error", String(payload.error));
fetch(aksrtData.ajaxUrl, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" },
credentials: "same-origin",
body: body.toString()
}).catch(function () {});
}
var scrollTimer = null;
function setHidden(hidden) {
wrap.classList.toggle("is-hidden", !!hidden);
}
function syncFromScrollBus() {
var body = document.body;
if (wrap.classList.contains("scroll-down-hide")) {
setHidden(body.classList.contains("scroll-down"));
}
if (wrap.classList.contains("scrolling-hide")) {
setHidden(true);
window.clearTimeout(scrollTimer);
scrollTimer = window.setTimeout(function () {
if (!body.classList.contains("scroll-down")) setHidden(false);
}, 160);
}
}
window.addEventListener("scroll", function () {
requestAnimationFrame(syncFromScrollBus);
}, { passive: true });
wrap.addEventListener("click", function (event) {
var btn = event.target.closest(".float-btn");
if (!btn) return;
if (btn.getAttribute("href") === "#") {
event.preventDefault();
}
if (btn.hasAttribute("data-action") && btn.getAttribute("data-action") === "toggle-theme") {
event.preventDefault();
if (window.aksrt && typeof aksrt.toggleTheme === "function") {
aksrt.toggleTheme();
} else {
document.documentElement.classList.toggle("dark");
document.body.classList.toggle("dark-theme");
}
}
btn.classList.remove("is-rippling");
window.requestAnimationFrame(function () {
btn.classList.add("is-rippling");
window.setTimeout(function () {
btn.classList.remove("is-rippling");
}, 600);
});
});
}
function initReadingProgress() {
var bar = document.getElementById("reading-progress-global");
if (!bar) return;
function update() {
var doc = document.documentElement;
var scrollable = doc.scrollHeight - window.innerHeight;
var pct = scrollable <= 0 ? 100 : Math.min(100, Math.max(0, (window.scrollY / scrollable) * 100));
bar.style.width = pct + "%";
bar.setAttribute("aria-valuenow", String(Math.round(pct)));
}
window.addEventListener("scroll", update, { passive: true });
window.addEventListener("resize", update, { passive: true });
update();
}
function initNavScrollState() {
// Zibll: hide is CSS on body.scroll-down + header.scroll-down-hide.
// Keep is-scrolled on .header for optional consumers.
var header = document.querySelector(".header");
var ticking = false;
function update() {
ticking = false;
var body = document.body;
if (header) {
header.classList.toggle("is-scrolled", body.classList.contains("body-scroll"));
}
}
function onScroll() {
if (!ticking) {
window.requestAnimationFrame(update);
ticking = true;
}
}
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll, { passive: true });
update();
}
window.AksrtFrontend.register("aksrt-floating-buttons", function () { initFloatingButtons(); });
window.AksrtFrontend.register("aksrt-back-to-top", function () { initBackToTop(); });
window.AksrtFrontend.register("aksrt-reading-progress", function () { initReadingProgress(); });
window.AksrtFrontend.register("aksrt-nav-scroll-state", function () { initNavScrollState(); });
})();
-459
View File
@@ -1,459 +0,0 @@
/**
* AKSRT Search Panel — desktop panel, mobile overlay, history, suggestions
*/
(function () {
"use strict";
function initSearchPanel() {
var mobileOverlay = document.getElementById("tabbar-search-overlay");
var mobileInput = document.getElementById("tabbar-search-input");
var mobileClose = document.getElementById("tabbar-search-close");
var mobileForm = mobileOverlay ? mobileOverlay.querySelector("form") : null;
var mobileTypeInput = document.getElementById("tabbar-search-type");
var mobileTypeButtons = document.querySelectorAll("#tabbar-search-types [data-search-type]");
var historyWrap = document.getElementById("tabbar-search-history");
var historySection = document.getElementById("tabbar-search-history-section");
var historyClear = document.getElementById("tabbar-search-history-clear");
var suggestionsWrap = document.getElementById("tabbar-search-suggestions");
var suggestionsSection = document.getElementById("tabbar-search-suggestions-section");
var searchForms = Array.prototype.slice.call(document.querySelectorAll("[data-aksrt-search-form]"));
if (!searchForms.length && !mobileForm) return;
var HISTORY_KEY = "aksrt-mobile-search-history";
var suggestTimer = null;
var searchConfig = (window.aksrtData && aksrtData.search) || {};
var historyEnabled = searchConfig.historyEnabled !== false;
var suggestionsEnabled = !!searchConfig.suggestionsEnabled;
if (historySection && !historyEnabled) {
historySection.hidden = true;
}
if (suggestionsSection && !suggestionsEnabled) {
suggestionsSection.hidden = true;
}
function getDesktopSearchType() {
if (!searchForms.length) return searchConfig.defaultType || "post";
var input = searchForms[0].querySelector('input[name="aksrt_search_type"]');
var value = input ? (input.value || "") : "";
return value || searchConfig.defaultType || "post";
}
function getDesktopCategory() {
if (!searchForms.length) return "0";
var input = searchForms[0].querySelector('input[name="aksrt_category"]');
return input ? (input.value || "0") : "0";
}
function syncSearchForms(type, category) {
searchForms.forEach(function (form) {
var typeInput = form.querySelector('input[name="aksrt_search_type"]');
if (typeInput) {
typeInput.value = type || searchConfig.defaultType || "post";
}
var categoryInput = form.querySelector('input[name="aksrt_category"]');
if (categoryInput) {
if ((type || searchConfig.defaultType || "post") === "post" && category && category !== "0") {
categoryInput.value = category;
} else {
categoryInput.value = "";
}
}
form.querySelectorAll("[data-search-type]").forEach(function (button) {
button.classList.toggle("is-active", button.getAttribute("data-search-type") === (type || searchConfig.defaultType || "post"));
});
});
}
function syncCategorySelectors(type, category) {
document.querySelectorAll("[data-search-category-select]").forEach(function (select) {
select.value = category && category !== "" ? category : "0";
select.disabled = (type || searchConfig.defaultType || "post") !== "post";
});
}
function getSearchType() {
if (mobileTypeInput) {
return mobileTypeInput.value || getDesktopSearchType();
}
return getDesktopSearchType();
}
function setSearchType(type) {
var nextType = type || searchConfig.defaultType || getDesktopSearchType();
if (mobileTypeInput) {
mobileTypeInput.value = nextType;
}
mobileTypeButtons.forEach(function (button) {
button.classList.toggle("is-active", button.getAttribute("data-search-type") === nextType);
});
syncSearchForms(nextType, getDesktopCategory());
syncCategorySelectors(nextType, getDesktopCategory());
requestSuggestions();
}
function readHistory() {
if (!historyEnabled) return [];
if (aksrtData.isLoggedIn) return [];
try {
var raw = localStorage.getItem(HISTORY_KEY);
var list = raw ? JSON.parse(raw) : [];
return Array.isArray(list) ? list : [];
} catch (e) {
return [];
}
}
function writeHistory(items) {
if (!historyEnabled) return;
if (aksrtData.isLoggedIn) return;
try {
localStorage.setItem(HISTORY_KEY, JSON.stringify(items.slice(0, 8)));
} catch (e) {}
}
function requestHistorySync(mode, items, callback) {
if (!historyEnabled) {
if (historySection) historySection.hidden = true;
if (typeof callback === "function") callback([]);
return;
}
if (!aksrtData.isLoggedIn) {
if (typeof callback === "function") callback(mode === "save" ? (items || []) : readHistory());
return;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", aksrtData.ajaxUrl, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.onload = function () {
if (typeof callback !== "function") return;
if (xhr.status < 200 || xhr.status >= 300) {
callback([]);
return;
}
try {
var json = JSON.parse(xhr.responseText);
callback(json.success && json.data && Array.isArray(json.data.items) ? json.data.items : []);
} catch (e) {
callback([]);
}
};
var body = "action=aksrt_search_history&nonce=" + encodeURIComponent(aksrtData.nonce) + "&mode=" + encodeURIComponent(mode);
if (mode === "save") {
body += "&items=" + encodeURIComponent(JSON.stringify(items || []));
}
xhr.send(body);
}
function pushHistory(keyword, type) {
if (!historyEnabled) return;
if (!keyword) return;
if (aksrtData.isLoggedIn) {
requestHistorySync("get", null, function (remoteItems) {
var nextRemote = (remoteItems || []).filter(function (item) {
return !(item && item.keyword === keyword && item.type === type);
});
nextRemote.unshift({ keyword: keyword, type: type });
requestHistorySync("save", nextRemote.slice(0, 8), function (savedItems) {
renderHistory(savedItems);
});
});
return;
}
var next = readHistory().filter(function (item) {
return !(item && item.keyword === keyword && item.type === type);
});
next.unshift({ keyword: keyword, type: type });
writeHistory(next);
renderHistory();
}
function renderHistory(providedItems) {
if (!historyWrap) return;
if (!historyEnabled) {
if (historySection) historySection.hidden = true;
historyWrap.innerHTML = "";
return;
}
if (historySection) {
historySection.hidden = false;
}
var items = Array.isArray(providedItems) ? providedItems : readHistory();
if (!items.length) {
historyWrap.innerHTML = '<div class="tabbar-search-overlay__empty">暂无搜索历史</div>';
if (historyClear) historyClear.style.display = "none";
return;
}
if (historyClear) historyClear.style.display = "inline-flex";
historyWrap.innerHTML = items.map(function (item) {
return '<button type="button" class="tabbar-search-overlay__history-item" data-history-keyword="' + encodeURIComponent(item.keyword) + '" data-history-type="' + encodeURIComponent(item.type || 'post') + '">' +
'<i class="fas fa-history"></i><span>' + item.keyword + '</span>' +
'</button>';
}).join("");
}
function renderSuggestions(items) {
if (!suggestionsWrap || !suggestionsSection) return;
if (!suggestionsEnabled) {
suggestionsSection.hidden = true;
suggestionsWrap.innerHTML = "";
return;
}
if (!items || !items.length) {
suggestionsWrap.innerHTML = '<div class="tabbar-search-overlay__empty">暂无匹配结果</div>';
suggestionsSection.hidden = false;
return;
}
suggestionsWrap.innerHTML = items.map(function (item) {
var meta = item.meta ? '<small>' + item.meta + '</small>' : '';
return '<a href="' + item.url + '" class="tabbar-search-overlay__suggestion-item">' +
'<span>' + item.title + '</span>' + meta +
'</a>';
}).join("");
suggestionsSection.hidden = false;
}
function requestSuggestions() {
if (!mobileInput || !suggestionsWrap || !suggestionsSection) return;
if (!suggestionsEnabled) {
suggestionsSection.hidden = true;
return;
}
var keyword = (mobileInput.value || "").trim();
if (suggestTimer) clearTimeout(suggestTimer);
if (keyword.length < 2) {
suggestionsSection.hidden = true;
return;
}
suggestTimer = setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open("POST", aksrtData.ajaxUrl, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.onload = function () {
if (xhr.status < 200 || xhr.status >= 300) return;
try {
var json = JSON.parse(xhr.responseText);
if (json.success && json.data && json.data.items) {
renderSuggestions(json.data.items);
}
} catch (e) {}
};
xhr.send(
"action=aksrt_search_suggestions&nonce=" + encodeURIComponent(aksrtData.nonce) +
"&q=" + encodeURIComponent(keyword) +
"&type=" + encodeURIComponent(getSearchType())
);
}, 180);
}
function setOpen(open) {
if (!mobileOverlay) return;
var toggles = document.querySelectorAll(".main-search-btn, .nav-search-toggle, [data-aksrt-open-search]");
if (open) {
mobileOverlay.removeAttribute("hidden");
mobileOverlay.setAttribute("aria-hidden", "false");
mobileOverlay.classList.add("is-open", "show");
document.body.classList.add("tabbar-search-open");
if (mobileInput) {
try { mobileInput.focus(); } catch (e) {}
}
if (historyEnabled) {
if (aksrtData.isLoggedIn) {
requestHistorySync("get", null, function (items) { renderHistory(items); });
} else {
renderHistory();
}
}
if (suggestionsEnabled) requestSuggestions();
toggles.forEach(function (btn) { btn.setAttribute("aria-expanded", "true"); });
} else {
mobileOverlay.setAttribute("hidden", "");
mobileOverlay.setAttribute("aria-hidden", "true");
mobileOverlay.classList.remove("is-open", "show");
document.body.classList.remove("tabbar-search-open");
if (suggestionsSection) suggestionsSection.hidden = true;
toggles.forEach(function (btn) { btn.setAttribute("aria-expanded", "false"); });
}
}
if (mobileOverlay) {
mobileOverlay.addEventListener("click", function (e) {
if (e.target === mobileOverlay) setOpen(false);
});
}
if (mobileClose) {
mobileClose.addEventListener("click", function () {
setOpen(false);
});
}
document.querySelectorAll(".main-search-btn, .nav-search-toggle, [data-aksrt-open-search]").forEach(function (btn) {
btn.addEventListener("click", function (e) {
// Top bar uses zibll .navbar-search slide — skip tabbar overlay.
var tgt = btn.getAttribute("data-target") || "";
if (tgt.indexOf("navbar-search") !== -1 || tgt.indexOf("main-search") !== -1) {
return;
}
e.preventDefault();
setOpen(true);
});
});
// Top-nav .navbar-search is toggled by aksrt-runtime (data-toggle-class="show").
// Do NOT redirect those clicks into the footer tabbar overlay.
// Only open tabbar overlay for explicit main-search-btn without .navbar-search target
// (handled above via .main-search-btn listeners).
if (historyClear) {
historyClear.addEventListener("click", function () {
if (aksrtData.isLoggedIn) {
requestHistorySync("save", [], function (savedItems) {
renderHistory(savedItems);
});
return;
}
writeHistory([]);
renderHistory();
});
}
if (historyWrap) {
historyWrap.addEventListener("click", function (e) {
var item = e.target.closest("[data-history-keyword]");
if (!item || !mobileInput) return;
mobileInput.value = decodeURIComponent(item.getAttribute("data-history-keyword") || "");
setSearchType(decodeURIComponent(item.getAttribute("data-history-type") || "post"));
requestSuggestions();
});
}
document.querySelectorAll("[data-search-category-select]").forEach(function (select) {
select.addEventListener("change", function () {
var nextCategory = this.value || "0";
syncSearchForms(getSearchType(), nextCategory);
syncCategorySelectors(getSearchType(), nextCategory);
});
});
mobileTypeButtons.forEach(function (button) {
button.addEventListener("click", function () {
setSearchType(button.getAttribute("data-search-type") || "post");
});
});
// Panel type buttons should also sync desktop/drawer forms
document.querySelectorAll("#tabbar-search-types [data-search-type], [data-aksrt-search-form] [data-search-type]").forEach(function (button) {
button.addEventListener("click", function () {
setSearchType(button.getAttribute("data-search-type") || "post");
});
});
if (mobileInput) {
mobileInput.addEventListener("input", requestSuggestions);
}
if (mobileForm) {
mobileForm.addEventListener("submit", function () {
if (mobileInput) {
pushHistory((mobileInput.value || "").trim(), getSearchType());
}
});
}
searchForms.forEach(function (form) {
if (form === mobileForm) return;
form.addEventListener("submit", function () {
if (!historyEnabled) return;
var input = form.querySelector('input[name="s"]');
var typeInput = form.querySelector('input[name="aksrt_search_type"]');
var keyword = input ? (input.value || "").trim() : "";
var type = typeInput ? (typeInput.value || searchConfig.defaultType || "post") : (searchConfig.defaultType || "post");
pushHistory(keyword, type);
});
});
syncSearchForms(getSearchType(), getDesktopCategory());
syncCategorySelectors(getSearchType(), getDesktopCategory());
setSearchType(getSearchType());
if (historyEnabled && aksrtData.isLoggedIn) {
requestHistorySync("get", null, function (items) {
renderHistory(items);
});
}
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && mobileOverlay && !mobileOverlay.hasAttribute("hidden")) {
setOpen(false);
}
});
window.__aksrtOpenSearchPanel = function () { setOpen(true); };
window.__aksrtCloseSearchPanel = function () { setOpen(false); };
initWidgetKeywordRefresh();
}
function initWidgetKeywordRefresh() {
document.querySelectorAll("[data-aksrt-search-keywords]").forEach(function (list) {
if (list.dataset.aksrtSearchKeywordsBound === "1") return;
list.dataset.aksrtSearchKeywordsBound = "1";
var keywords;
try {
keywords = JSON.parse(list.getAttribute("data-keywords") || "[]");
} catch (e) {
keywords = [];
}
if (!Array.isArray(keywords) || !keywords.length) return;
keywords = keywords
.map(function (keyword) { return String(keyword || "").trim(); })
.filter(function (keyword, index, values) { return keyword && values.indexOf(keyword) === index; });
var limit = Math.max(1, parseInt(list.getAttribute("data-keyword-limit") || "12", 10) || 12);
var searchType = list.getAttribute("data-search-type") || "post";
var searchUrl = list.getAttribute("data-search-url") || window.location.href;
var refreshButton = list.parentElement
? list.parentElement.querySelector("[data-aksrt-search-keyword-refresh]")
: null;
function shuffledKeywords() {
var shuffled = keywords.slice();
for (var i = shuffled.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var current = shuffled[i];
shuffled[i] = shuffled[j];
shuffled[j] = current;
}
return shuffled.slice(0, limit);
}
function renderKeywords() {
list.replaceChildren();
shuffledKeywords().forEach(function (keyword) {
var link = document.createElement("a");
var url = new URL(searchUrl, window.location.href);
url.searchParams.set("s", keyword);
url.searchParams.set("aksrt_search_type", searchType);
link.className = "aksrt-search-widget__kw";
link.href = url.toString();
link.textContent = keyword;
list.appendChild(link);
});
}
if (refreshButton) {
refreshButton.addEventListener("click", function () {
refreshButton.classList.add("is-refreshing");
renderKeywords();
window.setTimeout(function () {
refreshButton.classList.remove("is-refreshing");
}, 200);
});
}
});
}
window.AksrtFrontend.register("aksrt-search-panel", function () { initSearchPanel(); });
})();
-378
View File
@@ -1,378 +0,0 @@
/**
* AKSRT Hero & Swiper Initialization
*/
(function () {
"use strict";
window.AksrtSwipers = { new: [], scroll: [], tab: [] };
function initHeroSlider() {
if (typeof Swiper === "undefined") return;
// ===== Type A: .swiper-scroll =====
document.querySelectorAll(".swiper-scroll:not(.swiper-initialized)").forEach(function (el, index) {
var c_w = el.offsetWidth;
var firstSlide = el.querySelector(".swiper-wrapper > *");
var i_w = firstSlide ? firstSlide.offsetWidth : 200;
var slidesPerGroup = Math.max(1, Math.floor(c_w / i_w));
var option = {
slidesPerView: "auto",
freeMode: true,
freeModeSticky: true,
mousewheel: { forceToAxis: true },
slidesPerGroup: slidesPerGroup,
autoplay: el.dataset.autoplay ? {
delay: parseInt(el.dataset.interval || "4000", 10),
disableOnInteraction: false,
} : false,
loop: !!el.dataset.loop,
navigation: {
nextEl: el.querySelector(".swiper-button-next"),
prevEl: el.querySelector(".swiper-button-prev"),
},
};
el.classList.add("swiper-scroll-eq-" + index);
el.setAttribute("swiper-scroll-index", String(index));
window.AksrtSwipers.scroll[index] = new Swiper(el, option);
});
// ===== Type B: .swiper-tab =====
document.querySelectorAll(".swiper-tab:not(.swiper-initialized)").forEach(function (el, index) {
var speed = parseInt(el.dataset.speed || "0", 10) || Math.floor((el.offsetWidth + 1200) / 170) * 50;
speed = Math.max(300, speed);
var initialSlide = parseInt(el.getAttribute("active-index") || "0", 10);
var option = {
loop: false,
initialSlide: initialSlide,
autoHeight: true,
spaceBetween: 20,
autoplay: false,
speed: speed,
pagination: {
el: el.querySelector(".swiper-pagination"),
clickable: true,
},
};
var tabId = el.getAttribute("swiper-tab");
if (tabId) {
var tabNav = document.querySelector('[swiper-tab-nav="' + tabId + '"]');
if (tabNav && tabNav.swiper) {
option.thumbs = {
swiper: tabNav.swiper,
autoScrollOffset: 2,
};
}
}
el.classList.add("swiper-tab-eq-" + index);
el.setAttribute("swiper-tab-index", String(index));
window.AksrtSwipers.tab[index] = new Swiper(el, option);
});
// ===== Type C: .new-swiper =====
// Prefer data-swiper-config JSON (used by hero/banner templates), then data-* attrs.
document.querySelectorAll(".new-swiper:not(.swiper-initialized)").forEach(function (el, index) {
var jsonConfig = null;
if (el.dataset.swiperConfig) {
try {
jsonConfig = JSON.parse(el.dataset.swiperConfig);
} catch (e) {
jsonConfig = null;
}
}
if (!jsonConfig || typeof jsonConfig !== "object") {
jsonConfig = {};
}
var delay = parseInt(el.dataset.interval || "6000", 10);
if (jsonConfig.autoplay && typeof jsonConfig.autoplay === "object" && jsonConfig.autoplay.delay) {
delay = parseInt(jsonConfig.autoplay.delay, 10) || delay;
}
var autoplay;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "autoplay")) {
autoplay = jsonConfig.autoplay;
} else if (el.dataset.autoplay !== undefined) {
autoplay = {
delay: delay,
disableOnInteraction: false,
};
} else {
autoplay = false;
}
var speed = parseInt(el.dataset.speed || "0", 10) || Math.floor((el.offsetWidth + 1000) / 22) * 10;
if (jsonConfig.speed) {
speed = parseInt(jsonConfig.speed, 10) || speed;
}
speed = Math.max(400, speed);
if (!autoplay) speed = Math.floor(speed / 1.6);
var loop = Object.prototype.hasOwnProperty.call(jsonConfig, "loop")
? !!jsonConfig.loop
: !!el.dataset.loop;
var parallax = !!el.querySelector("[data-swiper-parallax],[data-swiper-parallax-scale]");
var effect = jsonConfig.effect || el.dataset.effect || "slide";
var direction = jsonConfig.direction || el.dataset.direction || "horizontal";
var spaceBetween = Object.prototype.hasOwnProperty.call(jsonConfig, "spaceBetween")
? parseInt(jsonConfig.spaceBetween, 10) || 0
: parseInt(el.dataset.spaceBetween || "0", 10);
var paginationType = el.dataset.paginationType || "bullets";
var autoHeight = Object.prototype.hasOwnProperty.call(jsonConfig, "autoHeight")
? !!jsonConfig.autoHeight
: el.hasAttribute("auto-height");
// Fixed-ratio modules (banner card) must not use autoHeight — it collapses absolute slides.
if (el.classList.contains("banner-module__swiper") || el.classList.contains("scale-height")) {
autoHeight = false;
}
var paginationEl = el.querySelector(".swiper-pagination, .header-components__pagination");
var prevBtn = el.querySelector(".swiper-button-prev, .banner-module__prev");
var nextBtn = el.querySelector(".swiper-button-next, .banner-module__next");
var pagination = false;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "pagination")) {
if (jsonConfig.pagination === false) {
pagination = false;
} else if (jsonConfig.pagination && typeof jsonConfig.pagination === "object") {
pagination = Object.assign(
{
el: paginationEl,
clickable: true,
},
jsonConfig.pagination
);
if (!pagination.el) pagination.el = paginationEl;
if (!pagination.el) pagination = false;
} else if (jsonConfig.pagination) {
pagination = paginationEl
? { el: paginationEl, type: paginationType, clickable: true }
: false;
}
} else {
pagination = paginationEl
? { el: paginationEl, type: paginationType, clickable: true }
: false;
}
var navigation = false;
if (Object.prototype.hasOwnProperty.call(jsonConfig, "navigation")) {
if (jsonConfig.navigation === false) {
navigation = false;
} else if (jsonConfig.navigation === true || jsonConfig.navigation) {
navigation = prevBtn && nextBtn
? { nextEl: nextBtn, prevEl: prevBtn }
: false;
}
} else {
navigation = {
nextEl: nextBtn,
prevEl: prevBtn,
};
}
var keyboard = Object.prototype.hasOwnProperty.call(jsonConfig, "keyboard")
? jsonConfig.keyboard
: { enabled: true };
el.classList.add("swiper-new-eq-" + index);
el.setAttribute("swiper-new-index", String(index));
var swiperArgs = {
loop: loop,
autoHeight: autoHeight,
direction: direction,
spaceBetween: spaceBetween,
parallax: parallax,
effect: effect,
autoplay: autoplay,
speed: speed,
pagination: pagination,
navigation: navigation,
keyboard: keyboard,
a11y: { prevSlideMessage: "上一张", nextSlideMessage: "下一张" },
on: {
slideChange: function () {
el.querySelectorAll(".aksrt-dplayer, video").forEach(function (media) {
if (media.pause) media.pause();
var dp = media.closest("[data-dplayer]");
if (dp && dp._dplayer) dp._dplayer.pause();
});
},
init: function () {
if (loop) {
el.querySelectorAll(".swiper-slide-duplicate img").forEach(function (img) {
img.classList.add("no-imgbox");
});
}
},
},
};
if (effect === "fade") {
swiperArgs.fadeEffect = Object.assign(
{ crossFade: true },
(jsonConfig.fadeEffect && typeof jsonConfig.fadeEffect === "object")
? jsonConfig.fadeEffect
: {}
);
}
if (pagination && paginationType === "thumbnail") {
swiperArgs.pagination.type = "bullets";
swiperArgs.pagination.bulletClass = "pagination-thumbnail-item";
swiperArgs.pagination.bulletActiveClass = "pagination-thumbnail-item-active";
swiperArgs.pagination.renderBullet = function (idx, className) {
var slide = this.slides[idx];
if (!slide) return "";
var img = slide.querySelector("img");
var src = img ? (img.dataset.src || img.src) : "";
if (src) {
return '<div class="' + className + '"><img' + window.aksrtGetLazyImageAttr('lazy_sider', src, 'aksrt-tilt-thumb') + ' alt=""></div>';
}
return "";
};
}
var swiperInstance = new Swiper(el, swiperArgs);
window.AksrtSwipers.new[index] = swiperInstance;
if (el.classList.contains("banner-module__swiper")) {
if (prevBtn) {
prevBtn.addEventListener("click", function (e) {
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
if (swiperInstance && !swiperInstance.destroyed) swiperInstance.slidePrev();
}, true);
}
if (nextBtn) {
nextBtn.addEventListener("click", function (e) {
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
if (swiperInstance && !swiperInstance.destroyed) swiperInstance.slideNext();
}, true);
}
}
});
// ===== Compat: data-swiper-config JSON =====
document.querySelectorAll("[data-swiper-config]:not(.swiper-initialized):not(.new-swiper):not(.swiper-scroll):not(.swiper-tab)").forEach(function (el) {
var config = {};
try { config = JSON.parse(el.dataset.swiperConfig || "{}"); } catch (e) {}
var paginationEl = el.querySelector(".swiper-pagination, .header-components__pagination");
var prevBtn = el.querySelector(".swiper-button-prev");
var nextBtn = el.querySelector(".swiper-button-next");
var defaults = {
effect: "fade",
fadeEffect: { crossFade: true },
loop: true,
speed: 600,
autoplay: { delay: 5000, disableOnInteraction: false },
pagination: paginationEl ? { el: paginationEl, type: "progressbar" } : false,
navigation: (prevBtn && nextBtn) ? { prevEl: prevBtn, nextEl: nextBtn } : false,
keyboard: { enabled: true },
a11y: { prevSlideMessage: "上一张", nextSlideMessage: "下一张" },
};
var finalConfig = Object.assign({}, defaults, config);
if (config.pagination && typeof config.pagination === "object") {
if (!config.pagination.el && paginationEl) config.pagination.el = paginationEl;
finalConfig.pagination = Object.assign({}, defaults.pagination || {}, config.pagination);
} else if (config.pagination === false) {
finalConfig.pagination = false;
}
if (config.navigation === true && prevBtn && nextBtn) {
finalConfig.navigation = { prevEl: prevBtn, nextEl: nextBtn };
}
new Swiper(el, finalConfig);
});
// Clickable slides
document.querySelectorAll(".swiper-slide[data-link]").forEach(function (slide) {
var link = slide.dataset.link;
if (link && link !== "#") {
slide.style.cursor = "pointer";
slide.addEventListener("click", function (e) {
if (e.target.closest(".header-components-search, .header-slider-search, .header-components-card, .header-slider-card, .hero__btn, .swiper-button-prev, .swiper-button-next, .swiper-pagination, .hero-search, a, button, input")) return;
window.location.href = link;
});
}
});
// Legacy hero__slides fallback
document.querySelectorAll(".hero__slides:not(.swiper-wrapper)").forEach(function (slider) {
var slides = slider.querySelectorAll(".hero__slide");
var dots = slider.querySelectorAll(".hero__dot");
var prevBtn = slider.closest("section")?.querySelector(".hero__btn--prev");
var nextBtn = slider.closest("section")?.querySelector(".hero__btn--next");
if (!slides.length || slides.length <= 1) return;
var autoplayInterval = parseInt(slider.dataset.autoplay || "5000", 10) || 5000;
var pauseOnHover = slider.dataset.pauseOnHover === "true";
var current = 0;
var timer = null;
var paused = false;
function show(index) {
index = ((index % slides.length) + slides.length) % slides.length;
slides[current].classList.remove("active");
if (dots[current]) dots[current].setAttribute("aria-selected", "false");
current = index;
slides[current].classList.add("active");
if (dots[current]) dots[current].setAttribute("aria-selected", "true");
}
function next() { show(current + 1); }
function prev() { show(current - 1); }
function startAutoplay() { stopAutoplay(); timer = setInterval(next, autoplayInterval); }
function stopAutoplay() { if (timer) clearInterval(timer); timer = null; }
function restart() { if (!paused) { stopAutoplay(); startAutoplay(); } }
show(0);
if (nextBtn) nextBtn.addEventListener("click", function () { next(); restart(); });
if (prevBtn) prevBtn.addEventListener("click", function () { prev(); restart(); });
dots.forEach(function (dot, i) { dot.addEventListener("click", function () { show(i); restart(); }); });
slider.setAttribute("tabindex", "-1");
slider.addEventListener("keydown", function (e) {
if (e.key === "ArrowRight") { next(); restart(); }
else if (e.key === "ArrowLeft") { prev(); restart(); }
});
if (pauseOnHover) {
slider.addEventListener("mouseenter", function () { paused = true; stopAutoplay(); });
slider.addEventListener("mouseleave", function () { paused = false; startAutoplay(); });
}
slides.forEach(function (slide) {
var link = slide.dataset.link;
if (link && link !== "#") {
slide.style.cursor = "pointer";
slide.addEventListener("click", function () { window.location.href = link; });
}
});
var touchStartX = 0;
slider.addEventListener("touchstart", function (e) { touchStartX = e.changedTouches[0].screenX; stopAutoplay(); }, { passive: true });
slider.addEventListener("touchend", function (e) {
var diff = touchStartX - e.changedTouches[0].screenX;
if (Math.abs(diff) > 50) { if (diff > 0) next(); else prev(); }
startAutoplay();
}, { passive: true });
startAutoplay();
document.addEventListener("visibilitychange", function () {
if (document.hidden) stopAutoplay();
else if (!paused) startAutoplay();
});
});
}
window.AksrtFrontend.register("aksrt-hero-slider", function () { initHeroSlider(); });
})();