/** * AKSRT Archive AJAX Filter */ (function () { "use strict"; function initArchiveFilter(root) { var scope = root || document; var bar = scope.querySelector(".archive-filter-bar--ajax[data-ajax-archive]"); if (!bar || bar.dataset.aksrtArchiveInit === "1") return; bar.dataset.aksrtArchiveInit = "1"; var archiveType = bar.dataset.ajaxArchive || "category"; var termId = parseInt(bar.dataset.termId, 10) || 0; var wrap = scope.querySelector("[data-ajax-wrap]"); if (!wrap) return; // 归档面与首页共用同一套骨架契约:.post_ajax_loader + .is-loading, // 不再使用独立 spinner 遮罩 / opacity 淡出。 var loading = wrap.querySelector(".post_ajax_loader"); var REST_BASE = "/wp-json/aksrt/v1/archive/posts"; var emptyText = archiveType === "tag" ? "该标签下暂无文章" : "该分类下暂无文章"; var state = { filter_cat: "", filter_tag: "", custom: {}, sort: "date", page: 1 }; var activeCat = bar.querySelector("[data-filter-cat].is-active"); if (activeCat) state.filter_cat = activeCat.dataset.filterCat || ""; var activeTag = bar.querySelector("[data-filter-tag].is-active"); if (activeTag) state.filter_tag = activeTag.dataset.filterTag || ""; var activeSort = bar.querySelector("[data-filter-sort].is-active"); if (activeSort) state.sort = activeSort.dataset.filterSort || "date"; // 自定义高级筛选维度:以当前 URL 参数为准(SSR active 状态与 URL 一致)。 if (bar.querySelector("[data-filter-dim]")) { new URLSearchParams(window.location.search).forEach(function (value, key) { if (bar.querySelector('[data-filter-dim="' + key + '"]')) { state.custom[key] = value; } }); } function buildUrl() { var params = new URLSearchParams(); params.set("archive_type", archiveType); params.set("term_id", String(termId)); if (state.filter_cat) params.set("filter_cat", state.filter_cat); if (state.filter_tag) params.set("filter_tag", state.filter_tag); if (Object.keys(state.custom).length) params.set("custom_filter", JSON.stringify(state.custom)); params.set("sort", state.sort || "date"); params.set("page", String(state.page)); return REST_BASE + "?" + params.toString(); } function updateActiveChips() { bar.querySelectorAll("[data-filter-cat]").forEach(function (el) { el.classList.toggle("is-active", (el.dataset.filterCat || "") === state.filter_cat); }); bar.querySelectorAll("[data-filter-tag]").forEach(function (el) { el.classList.toggle("is-active", (el.dataset.filterTag || "") === state.filter_tag); }); bar.querySelectorAll("[data-filter-sort]").forEach(function (el) { el.classList.toggle("is-active", (el.dataset.filterSort || "date") === state.sort); }); bar.querySelectorAll("[data-filter-dim]").forEach(function (el) { var current = state.custom[el.dataset.filterDim] || ""; el.classList.toggle("is-active", (el.dataset.filterDimValue || "") !== "" && (el.dataset.filterDimValue || "") === current); }); } function showLoading() { if (loading) loading.classList.add("is-loading"); } function hideLoading() { if (loading) loading.classList.remove("is-loading"); } function rebuildEmptyState() { var noResults = document.createElement("div"); noResults.className = "no-results content-stream__empty"; noResults.innerHTML = "

" + emptyText + "

"; wrap.appendChild(noResults); } function fetchPosts(pushState) { showLoading(); fetch(buildUrl(), { method: "GET", headers: { Accept: "application/json" }, credentials: "same-origin" }) .then(function (r) { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); }) .then(function (data) { hideLoading(); if (data.html !== undefined) { // 只清真实内容;骨架(.post_ajax_loader)与分页控件保留复用 —— // 与参考主题 post_ajax success 只 hide 不删的生命周期一致。 var keep = function (node) { return node === loading || node.classList.contains("post_ajax_loader") || node.classList.contains("ajax-pag"); }; Array.from(wrap.children).forEach(function (child) { if (!keep(child)) wrap.removeChild(child); }); if (data.html) { var temp = document.createElement("div"); temp.innerHTML = data.html; while (temp.firstChild) wrap.appendChild(temp.firstChild); } else { rebuildEmptyState(); } // legacy 事件顺序:先 post_ajax.ed,再全局 auto_fun 重扫 wrap.dispatchEvent(new CustomEvent("post_ajax.ed", { bubbles: true })); if (typeof window.auto_fun === "function") window.auto_fun(); } if (pushState !== false) { var url = new URL(window.location.href); url.searchParams.delete("orderby"); url.searchParams.delete("order"); url.searchParams.delete("paged"); url.searchParams.delete("aksrt_filter_cat"); url.searchParams.delete("aksrt_filter_tag"); bar.querySelectorAll("[data-filter-dim]").forEach(function (el) { url.searchParams.delete(el.dataset.filterDim); }); if (state.filter_cat) url.searchParams.set("aksrt_filter_cat", state.filter_cat); if (state.filter_tag) url.searchParams.set("aksrt_filter_tag", state.filter_tag); Object.keys(state.custom).forEach(function (key) { url.searchParams.set(key, state.custom[key]); }); if (state.sort) url.searchParams.set("orderby", state.sort); if (state.page > 1) url.searchParams.set("paged", String(state.page)); history.pushState({ aksrtArchive: true, state: Object.assign({}, state) }, "", url.toString()); } }) .catch(function () { hideLoading(); }); } bar.addEventListener("click", function (e) { var chip = e.target.closest("[data-filter-cat], [data-filter-tag], [data-filter-sort], [data-filter-dim]"); if (!chip) return; e.preventDefault(); var changed = false; if (chip.dataset.filterCat !== undefined) { var newCat = chip.dataset.filterCat; if (newCat !== state.filter_cat) { state.filter_cat = newCat; changed = true; } } if (chip.dataset.filterTag !== undefined) { var newTag = chip.dataset.filterTag; if (newTag !== state.filter_tag) { state.filter_tag = newTag; changed = true; } } if (chip.dataset.filterSort !== undefined) { var newSort = chip.dataset.filterSort || "date"; if (newSort !== state.sort) { state.sort = newSort; changed = true; } } if (chip.dataset.filterDim !== undefined) { var dimKey = chip.dataset.filterDim; var dimValue = chip.dataset.filterDimValue || ""; if (dimValue !== (state.custom[dimKey] || "")) { if (dimValue === "") { delete state.custom[dimKey]; } else { state.custom[dimKey] = dimValue; } changed = true; } } if (changed) { state.page = 1; updateActiveChips(); fetchPosts(true); } }); wrap.addEventListener("click", function (e) { var pageLink = e.target.closest(".pagination a, .nav-links a, a.page-numbers"); if (!pageLink || !wrap.contains(pageLink)) return; var href = pageLink.getAttribute("href"); if (!href) return; var match = href.match(/[?&]paged=(\d+)/); if (match) { e.preventDefault(); state.page = parseInt(match[1], 10) || 1; fetchPosts(true); } }); window.addEventListener("popstate", function (e) { if (e.state && e.state.aksrtArchive) { state = Object.assign(state, e.state.state); updateActiveChips(); fetchPosts(false); } }); } function init(root) { initArchiveFilter(root); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", function () { init(); }); } else { init(); } // AJAX 注入新内容后由 auto_fun 重扫(bar 级 data 标记保证幂等)。 if (window.jQuery) { window.jQuery(document).on("auto_fun", function () { init(); }); } })();