feat(navigation): hard-switch to Zibll navigation and Font Awesome 5
This commit is contained in:
1 parent
3c3ddac8be
commit
a0b84977a2
630 files changed
+101647
-11293
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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'
|
||||
);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
})();
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
})();
|
||||
@@ -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(); });
|
||||
})();
|
||||
@@ -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(); });
|
||||
})();
|
||||
@@ -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(); });
|
||||
})();
|
||||
Reference in new issue
Block a user