fix(frontend): rehydrate 根节点兼容 Element 无 getElementById
评论排序/点赞在 AJAX rehydrate 时 root 为 Element,调用 getElementById 抛 TypeError;改为 Document/Element 安全查找,并补上评论排序委托点击。
This commit is contained in:
@@ -142,10 +142,26 @@
|
||||
button.classList.toggle("is-loading", !!busy);
|
||||
}
|
||||
|
||||
function findInScope(scope, id) {
|
||||
scope = scope || document;
|
||||
if (!scope) return null;
|
||||
if (scope.nodeType === 9) {
|
||||
return scope.getElementById(id);
|
||||
}
|
||||
if (scope.nodeType === 1) {
|
||||
if (scope.id === id) return scope;
|
||||
return typeof scope.querySelector === "function"
|
||||
? scope.querySelector("#" + id)
|
||||
: null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function initInteractionBar(root) {
|
||||
var scope = root || document;
|
||||
var likeBtn = scope.getElementById("action-like");
|
||||
var favBtn = scope.getElementById("action-favorite");
|
||||
// Element roots (AJAX rehydrate) do not implement getElementById
|
||||
var likeBtn = findInScope(scope, "action-like");
|
||||
var favBtn = findInScope(scope, "action-favorite");
|
||||
|
||||
if (likeBtn && likeBtn.dataset.aksrtInteractionBound) return;
|
||||
if (favBtn && favBtn.dataset.aksrtInteractionBound) return;
|
||||
|
||||
@@ -555,18 +555,33 @@
|
||||
}
|
||||
|
||||
/* ====== 评论排序(最新 / 最早) ====== */
|
||||
/**
|
||||
* Locate #id within a rehydrate root.
|
||||
* Document has getElementById; Element roots (AJAX panels) only have querySelector.
|
||||
*/
|
||||
function findInScope(scope, id) {
|
||||
scope = scope || document;
|
||||
if (!scope) return null;
|
||||
if (scope.nodeType === 9) {
|
||||
return scope.getElementById(id);
|
||||
}
|
||||
if (scope.nodeType === 1) {
|
||||
if (scope.id === id) return scope;
|
||||
return typeof scope.querySelector === "function"
|
||||
? scope.querySelector("#" + id)
|
||||
: null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function initCommentOrder(root) {
|
||||
var scope = root || document;
|
||||
var commentsArea = scope.getElementById("comments");
|
||||
var commentsArea = findInScope(scope, "comments");
|
||||
if (!commentsArea) return;
|
||||
// Event delegation survives filter HTML replacement after AJAX rehydrate.
|
||||
if (commentsArea.dataset.orderInit === "1") return;
|
||||
commentsArea.dataset.orderInit = "1";
|
||||
|
||||
function getPaginationEl(root) {
|
||||
if (!root) return null;
|
||||
return root.querySelector(".aksrt-comment-pagination, .comment-navigation");
|
||||
}
|
||||
|
||||
function renderLoadingState() {
|
||||
var listContainer = commentsArea.querySelector("#comment-list");
|
||||
if (!listContainer) return;
|
||||
@@ -625,6 +640,25 @@
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
}
|
||||
|
||||
commentsArea.addEventListener("click", function (e) {
|
||||
var target = e.target;
|
||||
if (!target || typeof target.closest !== "function") return;
|
||||
|
||||
// 「只看作者」同时带 comment-orderby,需优先于排序按钮判断
|
||||
var authorBtn = target.closest(".comment-author-filter");
|
||||
if (authorBtn && commentsArea.contains(authorBtn)) {
|
||||
e.preventDefault();
|
||||
applyAuthorFilter(authorBtn.getAttribute("data-author-only") || "0");
|
||||
return;
|
||||
}
|
||||
|
||||
var orderBtn = target.closest(".comment-orderby[data-order]");
|
||||
if (orderBtn && commentsArea.contains(orderBtn)) {
|
||||
e.preventDefault();
|
||||
applyCommentOrder(orderBtn.getAttribute("data-order") || "newest");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.AksrtFrontend.register("aksrt-comment-system", function () { initCommentSystem(); });
|
||||
|
||||
Reference in New Issue
Block a user