feat(comments): 评论区按 Zibll 1:1 全量复刻
- 评论项/表单/工具栏/筛选/分页/空状态 DOM 全部替换为 zibll 原始类名 (li.comment、comt-main、comt-meta、list-inline、dropup 工具栏、 theme-pagination/pagenav、post_ajax_loader 骨架等) - 移植 zibll main.css L9412–9751 桌面 + 移动端评论样式, 缺失基础组件(title-theme/dropdown-menu/line-form/tab-nav-theme 等) 以 #comments 作用域补齐 - 删除全部 aksrt-comment__* 旧类名与旧样式,无兼容层 - JS 选择器对齐 zibll DOM:片段整块替换 #postcomments、骨架加载、 跳页输入、prepend 插入、addComment onclick 剥离, 移除 WP comment-reply enqueue 避免双 moveForm - 表情资源替换为 zibll 全套 gif(内容逐字节一致,git 无差异) - REST 后端 (CommentActions) 不变 验证:php -l 全部通过;5 个改动 JS 语法校验通过; node --test tests/widget-system/post-visual-contract.test.cjs 12/12 通过
This commit is contained in:
+72
-107
@@ -97,13 +97,13 @@
|
||||
}
|
||||
|
||||
function updateCommentCount(delta) {
|
||||
var countEl = document.querySelector('.comments-count');
|
||||
var countEl = document.querySelector('#comments .title-theme small');
|
||||
if (!countEl) return;
|
||||
var text = countEl.textContent || '';
|
||||
var match = text.match(/(\d+)/);
|
||||
if (!match) return;
|
||||
var nextCount = Math.max(0, parseInt(match[1], 10) + delta);
|
||||
countEl.textContent = '共 ' + nextCount + ' 条';
|
||||
countEl.textContent = text.replace(match[1], String(nextCount));
|
||||
}
|
||||
function handleResponse(responseText, statusCode) {
|
||||
try {
|
||||
@@ -316,9 +316,9 @@
|
||||
newComment.style.opacity = '0';
|
||||
newComment.style.transition = 'max-height 0.4s ease, opacity 0.3s ease';
|
||||
if (isReply && parentId) {
|
||||
var parentComment = document.querySelector('#comment-' + parentId + ', [data-comment-id="' + parentId + '"]');
|
||||
var parentComment = document.querySelector('#comment-' + parentId);
|
||||
if (parentComment) {
|
||||
var children = parentComment.querySelector('.children');
|
||||
var children = parentComment.querySelector(':scope > .children');
|
||||
if (!children) {
|
||||
children = document.createElement('ol');
|
||||
children.className = 'children';
|
||||
@@ -354,8 +354,15 @@
|
||||
}
|
||||
|
||||
function prependToCommentList(el) {
|
||||
var list = document.querySelector('.commentlist, #comment-list > ol, #comment-list');
|
||||
if (list) list.insertBefore(el, list.firstChild);
|
||||
var list = document.querySelector('#comments .commentlist');
|
||||
if (!list) return;
|
||||
// 插到筛选栏之后、最新评论之前
|
||||
var filter = list.querySelector('.comment-filter');
|
||||
if (filter && filter.nextSibling) {
|
||||
list.insertBefore(el, filter.nextSibling);
|
||||
} else {
|
||||
list.insertBefore(el, list.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function restoreRespondPosition() {
|
||||
@@ -471,66 +478,27 @@
|
||||
function getCurrentAuthorOnly() {
|
||||
var url = new URL(window.location.href);
|
||||
if (url.searchParams.get("aksrt_author_only") === "1") return true;
|
||||
var btn = document.querySelector("#comments .comment-author-filter");
|
||||
var btn = document.querySelector("#comments .btn-only-author");
|
||||
return !!(btn && btn.classList.contains("active") && btn.dataset.authorOnly === "0");
|
||||
}
|
||||
|
||||
function applyFragmentPayload(commentsArea, data, urlState) {
|
||||
if (!commentsArea || !data) return;
|
||||
if (!commentsArea || !data || !data.html) return;
|
||||
|
||||
if (data.filter_html) {
|
||||
var currentFilter = commentsArea.querySelector(".comment-filter");
|
||||
var temp = document.createElement("div");
|
||||
temp.innerHTML = data.filter_html;
|
||||
var newFilter = temp.firstElementChild;
|
||||
if (newFilter) {
|
||||
if (currentFilter) currentFilter.replaceWith(newFilter);
|
||||
else {
|
||||
var listAnchor = commentsArea.querySelector("#postcomments, #comment-list");
|
||||
if (listAnchor && listAnchor.parentNode) {
|
||||
listAnchor.parentNode.insertBefore(newFilter, listAnchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// data.html 是完整的 <div id="postcomments">(含筛选、列表、分页)
|
||||
var tempList = document.createElement("div");
|
||||
tempList.innerHTML = data.html;
|
||||
var newListWrap = tempList.querySelector("#postcomments");
|
||||
if (!newListWrap) return;
|
||||
|
||||
var currentListWrap = commentsArea.querySelector("#postcomments");
|
||||
var currentList = commentsArea.querySelector("#comment-list");
|
||||
var currentEmpty = commentsArea.querySelector(".comments-empty");
|
||||
var tempList = document.createElement("div");
|
||||
tempList.innerHTML = data.html || "";
|
||||
var newListWrap = tempList.querySelector("#postcomments");
|
||||
var newEmpty = tempList.querySelector(".comments-empty");
|
||||
|
||||
if (newListWrap) {
|
||||
if (currentListWrap) currentListWrap.replaceWith(newListWrap);
|
||||
else if (currentList) currentList.replaceWith(newListWrap);
|
||||
else commentsArea.appendChild(newListWrap);
|
||||
if (currentEmpty) currentEmpty.remove();
|
||||
} else if (newEmpty) {
|
||||
if (currentListWrap) currentListWrap.remove();
|
||||
if (currentList) currentList.remove();
|
||||
if (currentEmpty) currentEmpty.replaceWith(newEmpty);
|
||||
else commentsArea.appendChild(newEmpty);
|
||||
if (currentListWrap) {
|
||||
currentListWrap.replaceWith(newListWrap);
|
||||
} else {
|
||||
commentsArea.appendChild(newListWrap);
|
||||
}
|
||||
|
||||
var currentPagination = commentsArea.querySelector(".aksrt-comment-pagination, .comment-navigation, .pagenav.ajax-pag");
|
||||
if (data.pagination_html) {
|
||||
var ptemp = document.createElement("div");
|
||||
ptemp.innerHTML = data.pagination_html;
|
||||
var newPag = ptemp.firstElementChild;
|
||||
if (newPag) {
|
||||
if (currentPagination) currentPagination.replaceWith(newPag);
|
||||
else {
|
||||
var list = commentsArea.querySelector("#postcomments, #comment-list");
|
||||
if (list && list.parentNode) list.parentNode.insertBefore(newPag, list.nextSibling);
|
||||
}
|
||||
}
|
||||
} else if (currentPagination) {
|
||||
currentPagination.remove();
|
||||
}
|
||||
|
||||
var currentCount = commentsArea.querySelector(".comments-count");
|
||||
var currentCount = commentsArea.querySelector(".title-theme small");
|
||||
if (currentCount && data.count_text) currentCount.textContent = data.count_text;
|
||||
|
||||
if (urlState && window.history && typeof window.history.replaceState === "function") {
|
||||
@@ -562,20 +530,30 @@
|
||||
}
|
||||
|
||||
/* ====== 评论列表动态刷新 ====== */
|
||||
function showListLoading(commentsArea) {
|
||||
var list = commentsArea.querySelector(".commentlist");
|
||||
if (!list) return;
|
||||
// 保留筛选栏,清空条目并显示 zibll 骨架
|
||||
var filter = list.querySelector(".comment-filter");
|
||||
var loader = list.querySelector(".post_ajax_loader");
|
||||
var skeleton = loader ? loader.cloneNode(true) : null;
|
||||
Array.prototype.slice.call(list.children).forEach(function (child) {
|
||||
if (child !== filter && child !== loader) child.remove();
|
||||
});
|
||||
if (skeleton) {
|
||||
skeleton.style.display = "block";
|
||||
skeleton.removeAttribute("hidden");
|
||||
list.appendChild(skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
function reloadCommentList() {
|
||||
var commentsArea = document.getElementById('comments');
|
||||
var listContainer = document.getElementById('comment-list');
|
||||
if (!commentsArea && !listContainer) {
|
||||
if (!commentsArea) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
if (listContainer) {
|
||||
listContainer.innerHTML = '<li class="comment-loading-skeleton">' +
|
||||
'<div class="aksrt-comment"><div class="aksrt-comment__body">' +
|
||||
'<div style="height:60px;background:#f0f0f0;border-radius:8px;margin-bottom:10px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
|
||||
'<div style="height:20px;width:70%;background:#f0f0f0;border-radius:4px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
|
||||
'</div></div></li>';
|
||||
}
|
||||
showListLoading(commentsArea);
|
||||
|
||||
fetchCommentFragment({
|
||||
order: getCurrentCommentOrder(),
|
||||
@@ -583,7 +561,7 @@
|
||||
page: 1
|
||||
}).then(function (json) {
|
||||
if (json && json.success && json.data) {
|
||||
applyFragmentPayload(commentsArea || document, json.data, null);
|
||||
applyFragmentPayload(commentsArea, json.data, null);
|
||||
return;
|
||||
}
|
||||
throw new Error('fragment failed');
|
||||
@@ -622,13 +600,7 @@
|
||||
commentsArea.dataset.orderInit = "1";
|
||||
|
||||
function renderLoadingState() {
|
||||
var listContainer = commentsArea.querySelector("#comment-list");
|
||||
if (!listContainer) return;
|
||||
listContainer.innerHTML = '<li class="comment-loading-skeleton">' +
|
||||
'<div class="aksrt-comment"><div class="aksrt-comment__body">' +
|
||||
'<div style="height:60px;background:#f0f0f0;border-radius:8px;margin-bottom:10px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
|
||||
'<div style="height:20px;width:70%;background:#f0f0f0;border-radius:4px;animation:pulse 1.5s ease-in-out infinite;"></div>' +
|
||||
'</div></div></li>';
|
||||
showListLoading(commentsArea);
|
||||
}
|
||||
function applyCommentOrder(order) {
|
||||
if (order !== "newest" && order !== "oldest" && order !== "hottest") {
|
||||
@@ -685,7 +657,7 @@
|
||||
if (!target || typeof target.closest !== "function") return;
|
||||
|
||||
// 「只看作者」同时带 comment-orderby,需优先于排序按钮判断
|
||||
var authorBtn = target.closest(".comment-author-filter");
|
||||
var authorBtn = target.closest(".btn-only-author");
|
||||
if (authorBtn && commentsArea.contains(authorBtn)) {
|
||||
e.preventDefault();
|
||||
applyAuthorFilter(authorBtn.getAttribute("data-author-only") || "0");
|
||||
@@ -701,40 +673,33 @@
|
||||
}
|
||||
|
||||
|
||||
function initGuestFields() {
|
||||
var root = document.getElementById("comments") || document;
|
||||
root.querySelectorAll("[data-aksrt-guest-toggle]").forEach(function (btn) {
|
||||
if (btn.dataset.aksrtGuestBound === "1") return;
|
||||
btn.dataset.aksrtGuestBound = "1";
|
||||
var wrap = btn.closest(".comment-form__guest");
|
||||
var fields = wrap ? wrap.querySelector("[data-aksrt-guest-fields]") : null;
|
||||
if (!fields) return;
|
||||
btn.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
var open = btn.getAttribute("aria-expanded") === "true";
|
||||
btn.setAttribute("aria-expanded", open ? "false" : "true");
|
||||
if (open) {
|
||||
fields.setAttribute("hidden", "");
|
||||
fields.classList.remove("is-open");
|
||||
} else {
|
||||
fields.removeAttribute("hidden");
|
||||
fields.classList.add("is-open");
|
||||
var first = fields.querySelector("input");
|
||||
if (first) first.focus();
|
||||
}
|
||||
});
|
||||
// Auto-open if browser restored values or validation fails later.
|
||||
var form = btn.closest("form");
|
||||
if (form) {
|
||||
form.addEventListener("invalid", function () {
|
||||
fields.removeAttribute("hidden");
|
||||
fields.classList.add("is-open");
|
||||
btn.setAttribute("aria-expanded", "true");
|
||||
}, true);
|
||||
}
|
||||
/* ====== 数字分页跳页(zibll pag-jump) ====== */
|
||||
function jumpToCommentPage(page) {
|
||||
page = parseInt(page, 10) || 1;
|
||||
var url = new URL(window.location.href);
|
||||
url.searchParams.set("cpage", String(page));
|
||||
url.hash = "comments";
|
||||
window.location.href = url.toString();
|
||||
}
|
||||
|
||||
function initCommentPageJump() {
|
||||
document.addEventListener("click", function (e) {
|
||||
var jump = e.target.closest ? e.target.closest("#comments .pag-jump") : null;
|
||||
if (!jump) return;
|
||||
e.preventDefault();
|
||||
var input = jump.querySelector(".jump-input");
|
||||
if (input) jumpToCommentPage(input.value);
|
||||
});
|
||||
document.addEventListener("keydown", function (e) {
|
||||
if (e.key !== "Enter") return;
|
||||
var input = e.target;
|
||||
if (!input || !input.classList || !input.classList.contains("jump-input")) return;
|
||||
if (!input.closest("#comments .pagenav")) return;
|
||||
e.preventDefault();
|
||||
jumpToCommentPage(input.value);
|
||||
});
|
||||
}
|
||||
|
||||
window.AksrtFrontend.register("aksrt-comment-system", function () { initCommentSystem(); initGuestFields(); });
|
||||
window.AksrtFrontend.register("aksrt-comment-system", function () { initCommentSystem(); initCommentPageJump(); });
|
||||
window.AksrtFrontend.register("aksrt-comment-order", function (root) { initCommentOrder(root); });
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user