fix: 子菜单高亮改由 hashchange 统一驱动(issue #131)

浏览器实测(WebBridge)发现同页子菜单点击后页签切换正常但
子项高亮不跟随:原实现依赖子项点击处理器更新高亮,存在竞态。
改为统一数据流:子项一律默认导航改 hash → hashchange 同时驱动
页内 Tab 切换与 .pro-subitem 高亮同步,跨页直达/分享 URL 路径不变。

实测验证:admin/#audit|#kb|#models 连续切换,hash/页签/高亮三者同步
This commit is contained in:
2026-08-05 17:33:39 +08:00
parent e9787ecb22
commit 870dbb9ce5
+16 -11
View File
@@ -184,23 +184,25 @@
a.href = prefix + m.url.replace(/\/$/, "/") + c.hash;
a.textContent = c.title;
a.title = c.title;
// 同页子菜单:只改 hash,由 bindPageTabs 的 hashchange 驱动切换
if (isActiveModule) {
a.addEventListener("click", function (e) {
e.preventDefault();
childBox.querySelectorAll(".pro-subitem").forEach(function (x) {
x.classList.remove("active");
});
a.classList.add("active");
location.hash = c.hash; // 触发 hashchange → 激活对应 Tab
});
}
// 子项统一走默认导航(同页 = 改 hash,跨页 = 整页加载);
// 高亮与 Tab 切换全部由 hashchange 统一驱动(见 syncSubHighlight /
// bindPageTabs),不再依赖子项点击处理器。
childBox.appendChild(a);
});
wrap.appendChild(childBox);
menu.appendChild(wrap);
}
/* hash → 子菜单高亮同步(同页切换与分享直达都经过这里) */
function syncSubHighlight() {
var h = activeChildKey();
menu.querySelectorAll(".pro-subitem").forEach(function (x) {
var href = x.getAttribute("href") || "";
var hash = href.indexOf("#") >= 0 ? href.slice(href.indexOf("#")) : "";
x.classList.toggle("active", !!h && hash === "#" + h);
});
}
function renderMenu(user) {
menu.innerHTML = "";
// AntD Menu.ItemGroup 风格分组标题
@@ -212,6 +214,7 @@
if (m.children && m.children.length) addSubMenu(m);
else addLeafItem(m.key, m.icon, m.title, prefix + m.url);
});
syncSubHighlight();
}
/* ---- 用户区(后端优先、本地降级由 session.js 内部处理) --------------- */
@@ -232,6 +235,8 @@
});
bindPageTabs();
// 子菜单高亮全局同步(同页 hash 切换 / 分享直达 / 跨页返回)
window.addEventListener("hashchange", syncSubHighlight);
}
if (document.readyState === "loading") {