fix(pagination): align AJAX load-more loading state with reference
Loading indication now matches the reference theme's post_ajax() contract:
- Stop overwriting the 加载更多 button label with 正在加载...; the button
keeps its own text and the .post_ajax_loader skeleton carries the busy
state instead.
- Add the reference fallback loader (.loading ring + 加载中...) when no
skeleton exists in the DOM, and reinsert the skeleton after the last
card on every page load like beforeSend does.
- Retext the loader string to 加载中... (zib__('loading')) and make the
ajax_trigger default a translatable string.
- Route ajax-list.js / comments.js / widgets frontend.js through the
.is-loading class instead of inline display, which outranked the class
rule and could freeze the skeleton shut.
- Drop the search.php inline display:none that defeated .is-loading, and
remove the unproduced .post-ajax-loader / [data-aksrt-ajax-loader] shims.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e506309434
commit
b5f37d6d46
10 files changed
+59
-49
No files matched your search
@@ -48,13 +48,13 @@
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
// 骨架开关统一走 .is-loading(modal-runtime.css),不写 inline display:
|
||||
// 内联样式优先级高于类规则,一旦残留会让后续骨架永远打不开。
|
||||
function showLoader(container) {
|
||||
if (!container) return;
|
||||
var loader = container.querySelector(".post_ajax_loader, .post-ajax-loader, [data-aksrt-ajax-loader]");
|
||||
var loader = container.querySelector(".post_ajax_loader");
|
||||
if (loader) {
|
||||
loader.classList.add("is-loading");
|
||||
loader.hidden = false;
|
||||
loader.style.display = "";
|
||||
return;
|
||||
}
|
||||
container.classList.add("is-ajax-loading");
|
||||
@@ -62,13 +62,10 @@
|
||||
|
||||
function hideLoader(container) {
|
||||
if (!container) return;
|
||||
var loader = container.querySelector(".post_ajax_loader, .post-ajax-loader, [data-aksrt-ajax-loader]");
|
||||
var loader = container.querySelector(".post_ajax_loader");
|
||||
if (loader) {
|
||||
loader.classList.remove("is-loading");
|
||||
if (loader.hasAttribute("data-aksrt-ajax-loader-hide")) {
|
||||
loader.hidden = true;
|
||||
loader.style.display = "none";
|
||||
}
|
||||
return;
|
||||
}
|
||||
container.classList.remove("is-ajax-loading");
|
||||
}
|
||||
@@ -188,8 +185,6 @@
|
||||
Array.prototype.slice.call(container.children).forEach(function (child) {
|
||||
if (
|
||||
child.classList.contains("post_ajax_loader") ||
|
||||
child.classList.contains("post-ajax-loader") ||
|
||||
child.hasAttribute("data-aksrt-ajax-loader") ||
|
||||
child.classList.contains("ajax-pag")
|
||||
) {
|
||||
return;
|
||||
|
||||
@@ -465,7 +465,8 @@
|
||||
if (child !== filter && child !== loader) child.remove();
|
||||
});
|
||||
if (skeleton) {
|
||||
skeleton.style.display = "block";
|
||||
// 骨架开关走 .is-loading 类(modal-runtime.css),克隆时同步清理状态。
|
||||
skeleton.classList.add("is-loading");
|
||||
skeleton.removeAttribute("hidden");
|
||||
list.appendChild(skeleton);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
var triggerText = (window.aksrtData && aksrtData.ajaxTrigger) || "加载更多";
|
||||
var nomoreText = (window.aksrtData && aksrtData.ajaxNomore) || "没有更多了";
|
||||
var loadingText = (window.aksrtData && aksrtData.ajaxLoading) || "正在加载...";
|
||||
var errorText = (window.aksrtData && aksrtData.ajaxLoadError) || "加载失败,请重试";
|
||||
|
||||
containers.forEach(function (container) {
|
||||
@@ -51,18 +50,37 @@
|
||||
target = container.parentElement.querySelector(".post-grid, .comment-list, .commentlist, .content-stream__list");
|
||||
}
|
||||
|
||||
// 参考主题兜底 loader:DOM 里没有骨架时补一个 .loading 转圈 + 文案,
|
||||
// 绝不用按钮自身文字来表达加载态。
|
||||
function fallbackLoader() {
|
||||
var text = (window.aksrtData && aksrtData.ajaxLoading) || "加载中...";
|
||||
return (
|
||||
'<div class="mb20"><div class="text-center muted-2-color mt20">' +
|
||||
'<i class="loading mr10"></i>' + text +
|
||||
'</div></div>'
|
||||
);
|
||||
}
|
||||
|
||||
function showSkeleton() {
|
||||
if (!target) return;
|
||||
// PHP 产出下划线类名 post_ajax_loader;这里同时兼容连字符写法。
|
||||
var loader = target.querySelector(".post_ajax_loader, .post-ajax-loader");
|
||||
if (loader) {
|
||||
loader.classList.add("is-loading");
|
||||
var loader = target.querySelector(".post_ajax_loader");
|
||||
if (!loader) {
|
||||
loader = document.createElement("div");
|
||||
loader.className = "post_ajax_loader";
|
||||
loader.innerHTML = fallbackLoader();
|
||||
}
|
||||
// 参考主题 beforeSend:骨架每次翻页都挪到列表末尾(分页控件之前),
|
||||
// 紧贴最后一张卡片、位于「加载更多」按钮上方。
|
||||
target.insertBefore(
|
||||
loader,
|
||||
container.parentNode === target ? container : null
|
||||
);
|
||||
loader.classList.add("is-loading");
|
||||
}
|
||||
|
||||
function hideSkeleton() {
|
||||
if (!target) return;
|
||||
var loader = target.querySelector(".post_ajax_loader, .post-ajax-loader");
|
||||
var loader = target.querySelector(".post_ajax_loader");
|
||||
if (loader) {
|
||||
loader.classList.remove("is-loading");
|
||||
}
|
||||
@@ -72,13 +90,11 @@
|
||||
container.classList.remove("ias-pending");
|
||||
if (markNomore && loadMoreBtn) {
|
||||
loadMoreBtn.innerHTML = nomoreText;
|
||||
loadMoreBtn.classList.remove("is-loading");
|
||||
loadMoreBtn.classList.add("ajax-nomore");
|
||||
var nextWrap = loadMoreBtn.closest(".next-page");
|
||||
if (nextWrap) nextWrap.classList.add("no-more");
|
||||
loadMoreBtn.style.pointerEvents = "none";
|
||||
} else if (loadMoreBtn && !loadMoreBtn.classList.contains("ajax-nomore")) {
|
||||
loadMoreBtn.classList.remove("is-loading");
|
||||
if (failed) {
|
||||
loadMoreBtn.textContent = errorText;
|
||||
} else {
|
||||
@@ -93,7 +109,6 @@
|
||||
stopInfinite(false);
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.textContent = message || errorText;
|
||||
loadMoreBtn.classList.remove("is-loading");
|
||||
loadMoreBtn.classList.remove("ajax-nomore");
|
||||
loadMoreBtn.style.pointerEvents = "";
|
||||
}
|
||||
@@ -107,12 +122,8 @@
|
||||
}
|
||||
|
||||
loading = true;
|
||||
// 骨架开关统一走 .is-loading(modal-runtime.css),不要直接写
|
||||
// display:flex —— 那会让卡片型骨架挤成一行而不是纵向堆叠。
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.classList.add("is-loading");
|
||||
loadMoreBtn.textContent = loadingText;
|
||||
}
|
||||
// 加载态的呈现完全交给列表末尾的骨架(参考主题 post_ajax beforeSend
|
||||
// 只操作 .post_ajax_loader,不触碰「加载更多」按钮自身的文字)。
|
||||
showSkeleton();
|
||||
|
||||
var action = isComment ? "aksrt_load_more_comments" : "aksrt_load_more_posts";
|
||||
@@ -199,7 +210,6 @@
|
||||
loading = false;
|
||||
hideSkeleton();
|
||||
if (loadMoreBtn && !loadMoreBtn.classList.contains("ajax-nomore") && !failed) {
|
||||
loadMoreBtn.classList.remove("is-loading");
|
||||
loadMoreBtn.innerHTML = triggerText;
|
||||
if (mode === "infinite") {
|
||||
var lazyTrigger = clickTarget.closest(".next-page") || clickTarget;
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"aksrt-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("aksrt-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.AksrtModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.aksrtData||window2.aksrt||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/aksrt/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&Line truncated
|
||||
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"aksrt-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("aksrt-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.AksrtModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.aksrtData||window2.aksrt||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/aksrt/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&Line truncated
|
||||
Reference in new issue
Block a user