修复手机端子菜单无法显示的问题
This commit is contained in:
parent
3b3dfe9704
commit
ca98ef4b18
@ -8,52 +8,57 @@ export default function Nav({ color = "#fab758" }) {
|
|||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Dynamically import Bootstrap
|
|
||||||
import("bootstrap").then((Bootstrap) => {
|
|
||||||
const CLASS_NAME = "has-child-dropdown-show";
|
|
||||||
|
|
||||||
// Save the original toggle function
|
|
||||||
const originalToggle = Bootstrap.Dropdown.prototype.toggle;
|
|
||||||
|
|
||||||
// Override the toggle function
|
|
||||||
Bootstrap.Dropdown.prototype.toggle = function () {
|
|
||||||
// Remove the CLASS_NAME from all dropdowns
|
|
||||||
document.querySelectorAll("." + CLASS_NAME).forEach(function (e) {
|
|
||||||
e.classList.remove(CLASS_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Traverse up through the closest dropdown parents
|
|
||||||
let dd = this._element
|
|
||||||
.closest(".dropdown")
|
|
||||||
.parentNode.closest(".dropdown");
|
|
||||||
for (; dd && dd !== document; dd = dd.parentNode.closest(".dropdown")) {
|
|
||||||
dd.classList.add(CLASS_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the original toggle function
|
|
||||||
return originalToggle.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add event listeners for hide.bs.dropdown to remove the CLASS_NAME
|
|
||||||
document.querySelectorAll(".dropdown").forEach(function (dd) {
|
|
||||||
dd.addEventListener("hide.bs.dropdown", function (e) {
|
|
||||||
if (this.classList.contains(CLASS_NAME)) {
|
|
||||||
this.classList.remove(CLASS_NAME);
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取菜单数据
|
// 获取菜单数据
|
||||||
fetch("/api/get-menu")
|
fetch("/api/get-menu")
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => setMenu(data.menu || []));
|
.then((data) => setMenu(data.menu || []));
|
||||||
|
|
||||||
// Optional cleanup function for any potential side effects
|
// 点击外部区域关闭下拉菜单
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (!event.target.closest('.dropdown')) {
|
||||||
|
document.querySelectorAll('.dropdown-menu').forEach(menu => {
|
||||||
|
menu.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为多级下拉菜单添加事件监听器
|
||||||
|
const handleDropdownEvents = () => {
|
||||||
|
document.querySelectorAll('.dropdown-submenu').forEach(submenu => {
|
||||||
|
submenu.addEventListener('mouseenter', function() {
|
||||||
|
const dropdownMenu = this.querySelector('.dropdown-menu');
|
||||||
|
if (dropdownMenu) {
|
||||||
|
dropdownMenu.style.display = 'block';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
submenu.addEventListener('mouseleave', function() {
|
||||||
|
const dropdownMenu = this.querySelector('.dropdown-menu');
|
||||||
|
if (dropdownMenu) {
|
||||||
|
dropdownMenu.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 等待 DOM 加载完成后初始化
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', handleDropdownEvents);
|
||||||
|
} else {
|
||||||
|
// 延迟执行,确保菜单已经渲染
|
||||||
|
setTimeout(handleDropdownEvents, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加全局点击事件监听器
|
||||||
|
document.addEventListener('click', handleClickOutside);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// Cleanup code here (if needed)
|
// 清理事件监听器
|
||||||
|
document.removeEventListener('click', handleClickOutside);
|
||||||
|
document.querySelectorAll('.dropdown-submenu').forEach(submenu => {
|
||||||
|
submenu.removeEventListener('mouseenter', handleDropdownEvents);
|
||||||
|
submenu.removeEventListener('mouseleave', handleDropdownEvents);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -85,10 +90,15 @@ export default function Nav({ color = "#fab758" }) {
|
|||||||
)}
|
)}
|
||||||
{/* 右侧小三角,负责展开下拉 */}
|
{/* 右侧小三角,负责展开下拉 */}
|
||||||
<a
|
<a
|
||||||
className={`${hasHref ? "dropdown-toggle" : (level > 0 ? "dropdown-item" : "nav-link") + " dropdown-toggle"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${!hasHref && pathname === item.href ? "!text-[var(--current-color)]" : ""}`}
|
className={`${hasHref ? "dropdown-toggle" : (level > 0 ? "dropdown-item" : "nav-link")} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${!hasHref && pathname === item.href ? "!text-[var(--current-color)]" : ""}`}
|
||||||
href="#"
|
href="#"
|
||||||
data-bs-toggle="dropdown"
|
onClick={(e) => {
|
||||||
aria-expanded="false"
|
e.preventDefault();
|
||||||
|
const dropdownMenu = e.target.closest('.dropdown').querySelector('.dropdown-menu');
|
||||||
|
if (dropdownMenu) {
|
||||||
|
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
|
||||||
|
}
|
||||||
|
}}
|
||||||
style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}}
|
style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}}
|
||||||
>
|
>
|
||||||
{hasHref ? <span className="sr-only">展开</span> : item.label}
|
{hasHref ? <span className="sr-only">展开</span> : item.label}
|
||||||
@ -117,6 +127,115 @@ export default function Nav({ color = "#fab758" }) {
|
|||||||
return (
|
return (
|
||||||
<ul className="navbar-nav" style={{ "--current-color": color }}>
|
<ul className="navbar-nav" style={{ "--current-color": color }}>
|
||||||
{renderMenu(menu)}
|
{renderMenu(menu)}
|
||||||
|
<style jsx>{`
|
||||||
|
.navbar-nav .dropdown-submenu {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .dropdown-submenu .dropdown-menu {
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
margin-top: -1px;
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .dropdown-submenu:hover > .dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu.dropend .dropdown-menu {
|
||||||
|
left: 100%;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu > .dropdown-toggle::after {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.255em;
|
||||||
|
vertical-align: 0.255em;
|
||||||
|
content: "";
|
||||||
|
border-top: 0.3em solid transparent;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 0.3em solid transparent;
|
||||||
|
border-left: 0.3em solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
min-width: 10rem;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #212529;
|
||||||
|
text-align: left;
|
||||||
|
list-style: none;
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
clear: both;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #212529;
|
||||||
|
text-align: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:hover,
|
||||||
|
.dropdown-item:focus {
|
||||||
|
color: #1e2125;
|
||||||
|
background-color: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
color: #6c757d;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover {
|
||||||
|
color: var(--current-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu .dropdown-submenu .dropdown-menu {
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保顶级下拉菜单正确显示 */
|
||||||
|
.navbar-nav > .dropdown > .dropdown-menu {
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 添加下拉箭头指示器 */
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.255em;
|
||||||
|
vertical-align: 0.255em;
|
||||||
|
content: "";
|
||||||
|
border-top: 0.3em solid;
|
||||||
|
border-right: 0.3em solid transparent;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-left: 0.3em solid transparent;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user