使用jetmenu配合elementor的tab切换时,点击tab切换导致菜单消失的问题
问题
实现如图效果时,我使用js让鼠标移动到对应tab上时就触发点击交互,但是菜单会消失
解决思路
尝试使用js控制显示逻辑,结果一直和jetmenu的逻辑打架,最后使用css强制菜单一直显示,要注意必须把菜单显示时,加到对应元素上的类名也一起加上去,不然会导致菜单里面内容的交互失效,再使用js彻底重写菜单显示与隐藏的逻辑。
代码
css
/* 锁定展开时,强制让 mega 容器可见并可点击 */
.jet-mega-menu-item-6843.force-open > .jet-mega-menu-mega-container {
display: block !important;
visibility: visible !important;
opacity: 1 !important;
pointer-events: auto !important;
}
js
document.addEventListener("DOMContentLoaded", function () {
// 仅在桌面端生效(JetMenu 断点是 768)
if (window.innerWidth < 768) return;
const menuItem = document.querySelector(".jet-mega-menu-item-6843");
if (!menuItem) return;
const inner = menuItem.querySelector(
".jet-mega-menu-item__inner[aria-expanded]"
);
const dropdown = menuItem.querySelector(".jet-mega-menu-mega-container");
const tabWrap = menuItem.querySelector(".elementor-element-1545c3c");
const tabs = tabWrap ? tabWrap.querySelectorAll("button") : [];
if (!inner || !dropdown || !tabWrap) return;
let closeTimer = null;
function addForceOpen() {
menuItem.classList.add("force-open");
inner.setAttribute("aria-expanded", "true");
}
function scheduleClose() {
// 轻微延迟,避免从 inner 移到 dropdown 的“空隙”瞬间被关
clearTimeout(closeTimer);
closeTimer = setTimeout(() => {
// 如果鼠标已不在整个 li 或其 dropdown 内,再关闭
if (!menuItem.matches(":hover") && !dropdown.matches(":hover")) {
menuItem.classList.remove("force-open");
inner.setAttribute("aria-expanded", "false");
}
}, 0);
}
// 进入整个菜单/下拉/Tab 区域,都强制打开
menuItem.addEventListener("mouseenter", addForceOpen, true);
dropdown.addEventListener("mouseenter", addForceOpen, true);
tabWrap.addEventListener("mouseenter", addForceOpen, true);
// 离开这些区域时,延迟尝试关闭
menuItem.addEventListener("mouseleave", scheduleClose, true);
dropdown.addEventListener("mouseleave", scheduleClose, true);
tabWrap.addEventListener("mouseleave", scheduleClose, true);
// 关键:当鼠标从“顶层按钮(inner)”移向“dropdown/tab”时,
// JetMenu 会在 inner 的 mouseleave 里把菜单关掉。
// 我们在捕获阶段判断 relatedTarget 仍在同一个 li 内,则下一帧重新强制打开,化解闪断。
inner.addEventListener(
"mouseleave",
function (e) {
const to = e.relatedTarget;
if (to && menuItem.contains(to)) {
// 下一帧把 force-open 扶起来,覆盖它刚刚的关闭
requestAnimationFrame(addForceOpen);
}
},
true
);
// Tab 悬停即切换,同时维持展开
tabs.forEach((btn) => {
btn.addEventListener("mouseenter", (e) => {
e.stopPropagation();
btn.click();
addForceOpen();
});
});
});