fix(comments): open the action dropdown with theme-owned delegation

The comment three-dot menu relied on the legacy data-toggle=dropdown
delegation living in comment-move-form.js; when that bundle chain does
not evaluate (stale cache or an earlier top-level error), the menu
appears dead. Move the comment action dropdown to its own top-level
document delegation in comments.js (data-aksrt-comment-drop), keep the
.open-driven CSS contract including the mobile drop-fixed-sm sheet,
sync aria-expanded, close on outside click / Escape / menu item click,
and stay idempotent for AJAX-injected comments.
This commit is contained in:
2026-09-20 13:55:03 +08:00
parent 7c730b83d6
commit 913958820c
3 changed files with 54 additions and 2 deletions
+49
View File
@@ -616,6 +616,51 @@
});
}
/* ====== 评论操作三点下拉(主题自有交互,替代 vendor data-toggle 遗留委托) ======
* 一次性文档级委托:AJAX 注入的新评论无需重绑;
* open 类驱动的 .dropdown-menu 显隐 CSS 契约(含移动端 drop-fixed-sm 底部抽屉)保持不变。 */
function closeAllCommentDropdowns() {
document.querySelectorAll("#postcomments .dropdown.open").forEach(function (wrap) {
wrap.classList.remove("open");
var trigger = wrap.querySelector("[data-aksrt-comment-drop]");
if (trigger) trigger.setAttribute("aria-expanded", "false");
});
}
function initCommentActionDropdowns() {
if (document.documentElement.dataset.aksrtCommentDropBound === "1") return;
document.documentElement.dataset.aksrtCommentDropBound = "1";
document.addEventListener("click", function (event) {
var trigger = event.target.closest ? event.target.closest("[data-aksrt-comment-drop]") : null;
if (trigger) {
event.preventDefault();
var wrap = trigger.closest(".dropdown");
if (!wrap) return;
var wasOpen = wrap.classList.contains("open");
closeAllCommentDropdowns();
if (!wasOpen) {
wrap.classList.add("open");
trigger.setAttribute("aria-expanded", "true");
}
return;
}
// 点击菜单项(举报/置顶/编辑/批准/删除)后收起菜单。
var menuItem = event.target.closest ? event.target.closest("#postcomments .dropdown.open .dropdown-menu a") : null;
if (menuItem) {
closeAllCommentDropdowns();
return;
}
if (!event.target.closest || !event.target.closest("#postcomments .dropdown.open")) {
closeAllCommentDropdowns();
}
});
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") closeAllCommentDropdowns();
});
}
function init() {
stripCommentUrlParams();
initCommentSystem();
@@ -623,6 +668,10 @@
initCommentOrder();
}
// 顶层立即绑定:纯文档级委托,不依赖 DOM 就绪与 init() 是否成功;
// 保证即使同文件后续初始化在异常环境中中断,三点菜单仍可开合。
initCommentActionDropdowns();
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
+1 -1
View File
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -224,7 +224,10 @@ if (!function_exists('aksrt_get_comments_action_dropdown_html')) :
}
$menu_icon = function_exists('aksrt_get_comment_icon') ? aksrt_get_comment_icon('menu_2') : '';
$icon_a = '<a href="javascript:;" class="muted-color padding-6" data-toggle="dropdown">' . $menu_icon . '</a>';
// 交互由主题自有 comments.js 委托处理(data-aksrt-comment-drop),
// 不用 vendor 的 data-toggle="dropdown" 遗留委托:该链路在部分环境
// 未注册/被早退,导致三点菜单点不开。open 类驱动的 CSS 契约不变。
$icon_a = '<a href="javascript:;" class="muted-color padding-6" data-aksrt-comment-drop aria-haspopup="true" aria-expanded="false" aria-label="' . esc_attr__('更多操作', 'aksrt') . '">' . $menu_icon . '</a>';
return '<span class="dropdown drop-fixed-sm padding-6">' . $icon_a . '<ul class="dropdown-menu">' . $lists . '</ul></span>';
}