对齐内容主线页骨架
This commit is contained in:
+40
-26
@@ -4,17 +4,19 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function initArchiveFilter() {
|
||||
var bar = document.querySelector(".archive-filter-bar--ajax[data-ajax-archive]");
|
||||
function initArchiveFilter(root) {
|
||||
var scope = root || document;
|
||||
var bar = scope.querySelector(".archive-filter-bar--ajax[data-ajax-archive]");
|
||||
if (!bar) return;
|
||||
|
||||
var archiveType = bar.dataset.ajaxArchive || "category";
|
||||
var termId = parseInt(bar.dataset.termId, 10) || 0;
|
||||
var wrap = document.querySelector("[data-ajax-wrap]");
|
||||
var wrap = scope.querySelector("[data-ajax-wrap]");
|
||||
if (!wrap) return;
|
||||
|
||||
var loading = wrap.querySelector(".archive__ajax-loading");
|
||||
var REST_BASE = "/wp-json/aksrt/v1/archive/posts";
|
||||
var emptyText = archiveType === "tag" ? "该标签下暂无文章" : "该分类下暂无文章";
|
||||
|
||||
var state = {
|
||||
filter_cat: "",
|
||||
@@ -24,14 +26,12 @@
|
||||
cf: {}
|
||||
};
|
||||
|
||||
// Read initial state from active chips
|
||||
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 || "latest";
|
||||
// custom_filter: read initial cf state from active chips
|
||||
bar.querySelectorAll("[data-filter-cf].is-active").forEach(function (el) {
|
||||
var dimKey = el.dataset.filterCf || "";
|
||||
var dimVal = el.dataset.filterCfVal || "";
|
||||
@@ -50,11 +50,13 @@
|
||||
params.set("sort", s ? s.orderby : "date");
|
||||
params.set("order", s ? s.order : "DESC");
|
||||
params.set("page", String(state.page));
|
||||
// custom_filter: pass active dimensions as JSON
|
||||
var cfActive = {};
|
||||
var hasCf = false;
|
||||
for (var cfK in state.cf) {
|
||||
if (state.cf[cfK]) { cfActive[cfK] = state.cf[cfK]; hasCf = true; }
|
||||
if (state.cf[cfK]) {
|
||||
cfActive[cfK] = state.cf[cfK];
|
||||
hasCf = true;
|
||||
}
|
||||
}
|
||||
if (hasCf) params.set("custom_filters", JSON.stringify(cfActive));
|
||||
return REST_BASE + "?" + params.toString();
|
||||
@@ -70,7 +72,6 @@
|
||||
bar.querySelectorAll("[data-filter-sort]").forEach(function (el) {
|
||||
el.classList.toggle("is-active", (el.dataset.filterSort || "latest") === state.sort);
|
||||
});
|
||||
// custom_filter: update cf chip active state
|
||||
bar.querySelectorAll("[data-filter-cf]").forEach(function (el) {
|
||||
var dimKey = el.dataset.filterCf || "";
|
||||
var dimVal = el.dataset.filterCfVal || "";
|
||||
@@ -89,6 +90,13 @@
|
||||
wrap.classList.remove("is-loading");
|
||||
}
|
||||
|
||||
function rebuildEmptyState() {
|
||||
var noResults = document.createElement("div");
|
||||
noResults.className = "no-results content-stream__empty";
|
||||
noResults.innerHTML = "<p>" + emptyText + "</p>";
|
||||
wrap.appendChild(noResults);
|
||||
}
|
||||
|
||||
function fetchPosts(pushState) {
|
||||
showLoading();
|
||||
fetch(buildUrl(), {
|
||||
@@ -103,7 +111,6 @@
|
||||
.then(function (data) {
|
||||
hideLoading();
|
||||
if (data.html !== undefined) {
|
||||
// Keep the loading element, replace the rest
|
||||
var children = Array.from(wrap.children);
|
||||
children.forEach(function (child) {
|
||||
if (child !== loading) wrap.removeChild(child);
|
||||
@@ -113,13 +120,9 @@
|
||||
temp.innerHTML = data.html;
|
||||
while (temp.firstChild) wrap.appendChild(temp.firstChild);
|
||||
} else {
|
||||
var noResults = document.createElement("div");
|
||||
noResults.className = "no-results";
|
||||
noResults.innerHTML = "<p>暂无文章</p>";
|
||||
wrap.appendChild(noResults);
|
||||
rebuildEmptyState();
|
||||
}
|
||||
// Re-init rehydratable modules for new content
|
||||
if (window.AksrtFrontend) AksrtFrontend.rehydrate(wrap, 'ajax');
|
||||
if (window.AksrtFrontend) AksrtFrontend.rehydrate(wrap, "ajax");
|
||||
}
|
||||
if (pushState !== false) {
|
||||
var url = new URL(window.location.href);
|
||||
@@ -128,18 +131,21 @@
|
||||
url.searchParams.delete("paged");
|
||||
url.searchParams.delete("aksrt_filter_cat");
|
||||
url.searchParams.delete("aksrt_filter_tag");
|
||||
// custom_filter: clean cf params
|
||||
url.searchParams.forEach(function (v, k) {
|
||||
if (k.indexOf("aksrt_cf_") === 0) url.searchParams.delete(k);
|
||||
});
|
||||
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);
|
||||
// custom_filter: set cf URL params
|
||||
for (var cfK2 in state.cf) {
|
||||
if (state.cf[cfK2]) url.searchParams.set("aksrt_cf_" + cfK2, state.cf[cfK2]);
|
||||
}
|
||||
if (state.sort === "oldest") { url.searchParams.set("orderby", "date"); url.searchParams.set("order", "asc"); }
|
||||
else if (state.sort === "popular") { url.searchParams.set("orderby", "comment_count"); url.searchParams.set("order", "desc"); }
|
||||
if (state.sort === "oldest") {
|
||||
url.searchParams.set("orderby", "date");
|
||||
url.searchParams.set("order", "asc");
|
||||
} else if (state.sort === "popular") {
|
||||
url.searchParams.set("orderby", "comment_count");
|
||||
url.searchParams.set("order", "desc");
|
||||
}
|
||||
if (state.page > 1) url.searchParams.set("paged", String(state.page));
|
||||
history.pushState({ aksrtArchive: true, state: Object.assign({}, state) }, "", url.toString());
|
||||
}
|
||||
@@ -157,17 +163,25 @@
|
||||
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 (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 (newTag !== state.filter_tag) {
|
||||
state.filter_tag = newTag;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (chip.dataset.filterSort !== undefined) {
|
||||
var newSort = chip.dataset.filterSort || "latest";
|
||||
if (newSort !== state.sort) { state.sort = newSort; changed = true; }
|
||||
if (newSort !== state.sort) {
|
||||
state.sort = newSort;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
// custom_filter: handle cf chip clicks
|
||||
if (chip.dataset.filterCf !== undefined) {
|
||||
var cfKey = chip.dataset.filterCf;
|
||||
var cfVal = chip.dataset.filterCfVal || "";
|
||||
@@ -184,7 +198,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Pagination within AJAX wrap
|
||||
wrap.addEventListener("click", function (e) {
|
||||
var pageLink = e.target.closest(".pagination a, .nav-links a, a.page-numbers");
|
||||
if (!pageLink || !wrap.contains(pageLink)) return;
|
||||
@@ -199,7 +212,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Handle browser back/forward
|
||||
window.addEventListener("popstate", function (e) {
|
||||
if (e.state && e.state.aksrtArchive) {
|
||||
state = Object.assign(state, e.state.state);
|
||||
@@ -209,5 +221,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
window.AksrtFrontend.register("aksrt-archive-filter", function () { initArchiveFilter(); });
|
||||
window.AksrtFrontend.register("aksrt-archive-filter", function (root) {
|
||||
initArchiveFilter(root);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -25,8 +25,13 @@
|
||||
var loading = false;
|
||||
var loadMoreBtn = container.querySelector(".aksrt-load-more-btn, .ajax-next");
|
||||
var indicator = container.querySelector(".aksrt-loading-indicator");
|
||||
// 目标容器:文章列表取 .post-grid,评论取 .comment-list
|
||||
var target = container.previousElementSibling;
|
||||
if (target && target.classList && target.classList.contains("content-stream__footer")) {
|
||||
target = target.previousElementSibling;
|
||||
}
|
||||
if (!target && container.parentElement) {
|
||||
target = container.parentElement.querySelector(".post-grid, .comment-list, .content-stream__list");
|
||||
}
|
||||
|
||||
function showSkeleton() {
|
||||
if (!target) return;
|
||||
@@ -96,10 +101,8 @@
|
||||
nextPage++;
|
||||
container.dataset.nextPage = String(nextPage);
|
||||
|
||||
// 重新初始化懒加载(新加载的图片)
|
||||
if (typeof initLazyLoad === "function") initLazyLoad();
|
||||
|
||||
// 如果没有更多页
|
||||
if (nextPage > maxPages || !res.data.has_more) {
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.textContent = nomoreText;
|
||||
@@ -124,7 +127,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 加载更多按钮点击
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.addEventListener("click", function(e) {
|
||||
e.preventDefault();
|
||||
@@ -154,55 +156,48 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 无限滚动:IntersectionObserver
|
||||
if (mode === "infinite" && "IntersectionObserver" in window) {
|
||||
// Comment containers respect commentIasAuto; if disabled, fall back to click-to-load
|
||||
if (isComment && window.aksrtData && aksrtData.commentIasAuto === false) {
|
||||
// Skip IntersectionObserver — load_more button already present
|
||||
} else {
|
||||
var sentinel = document.createElement("div");
|
||||
sentinel.className = "aksrt-scroll-sentinel";
|
||||
container.appendChild(sentinel);
|
||||
var lazyloadAction = container.dataset.lazyloadAction || "";
|
||||
var iasMax = isComment
|
||||
? ((window.aksrtData && typeof aksrtData.commentIasMax !== "undefined") ? parseInt(aksrtData.commentIasMax, 10) : 0)
|
||||
: ((window.aksrtData && typeof aksrtData.iasMax !== "undefined") ? parseInt(aksrtData.iasMax, 10) : 0);
|
||||
var initialPage = nextPage - 1; // page at init time
|
||||
var observer = new IntersectionObserver(
|
||||
function (entries) {
|
||||
if (entries[0].isIntersecting && !loading) {
|
||||
// iasMax = 0 means unlimited, otherwise limit additional pages
|
||||
if (iasMax > 0 && (nextPage - initialPage) >= iasMax) {
|
||||
// Reached ias max, show nomore and disconnect
|
||||
observer.disconnect();
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.textContent = nomoreText;
|
||||
loadMoreBtn.classList.add("ajax-nomore");
|
||||
loadMoreBtn.style.pointerEvents = "none";
|
||||
var sentinel = document.createElement("div");
|
||||
sentinel.className = "aksrt-scroll-sentinel";
|
||||
container.appendChild(sentinel);
|
||||
var lazyloadAction = container.dataset.lazyloadAction || "";
|
||||
var iasMax = isComment
|
||||
? ((window.aksrtData && typeof aksrtData.commentIasMax !== "undefined") ? parseInt(aksrtData.commentIasMax, 10) : 0)
|
||||
: ((window.aksrtData && typeof aksrtData.iasMax !== "undefined") ? parseInt(aksrtData.iasMax, 10) : 0);
|
||||
var initialPage = nextPage - 1;
|
||||
var observer = new IntersectionObserver(
|
||||
function (entries) {
|
||||
if (entries[0].isIntersecting && !loading) {
|
||||
if (iasMax > 0 && (nextPage - initialPage) >= iasMax) {
|
||||
observer.disconnect();
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.textContent = nomoreText;
|
||||
loadMoreBtn.classList.add("ajax-nomore");
|
||||
loadMoreBtn.style.pointerEvents = "none";
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
loadNextPage();
|
||||
}
|
||||
loadNextPage();
|
||||
}
|
||||
},
|
||||
{ rootMargin: "400px" }
|
||||
);
|
||||
if (lazyloadAction === "ias") {
|
||||
container.classList.add("ias-pending");
|
||||
}
|
||||
observer.observe(sentinel);
|
||||
},
|
||||
{ rootMargin: "400px" }
|
||||
);
|
||||
if (lazyloadAction === "ias") {
|
||||
container.classList.add("ias-pending");
|
||||
}
|
||||
observer.observe(sentinel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ====== 图片懒加载 ====== */
|
||||
function initLazyLoad(root) {
|
||||
var scope = root || document;
|
||||
var lazyImages = scope.querySelectorAll("img.aksrt-lazy");
|
||||
if (!lazyImages.length) return;
|
||||
|
||||
// 不支持 IntersectionObserver 时直接加载所有图片
|
||||
if (!("IntersectionObserver" in window)) {
|
||||
lazyImages.forEach(function (img) {
|
||||
var src = img.dataset.src;
|
||||
@@ -230,13 +225,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新图片预加载
|
||||
var tempImg = new Image();
|
||||
tempImg.onload = function () {
|
||||
img.src = src;
|
||||
img.classList.remove("aksrt-lazy");
|
||||
img.classList.add("aksrt-loaded");
|
||||
// 移除骨架
|
||||
var skeleton = img.previousElementSibling;
|
||||
if (skeleton && skeleton.classList.contains("aksrt-skeleton")) {
|
||||
skeleton.remove();
|
||||
@@ -245,7 +238,6 @@
|
||||
tempImg.onerror = function () {
|
||||
img.classList.remove("aksrt-lazy");
|
||||
img.classList.add("aksrt-error");
|
||||
// 移除骨架
|
||||
var skeleton = img.previousElementSibling;
|
||||
if (skeleton && skeleton.classList.contains("aksrt-skeleton")) {
|
||||
skeleton.remove();
|
||||
|
||||
Reference in New Issue
Block a user