Bootstrap 5导航栏下拉菜单仅展开不收起问题求助
Bootstrap 5 导航栏下拉菜单移动端无法收起的修复方案
问题原因
- CSS 规则冲突:移动端媒体查询中强制设置
.dropdown:hover > .dropdown-menu {display: block},导致点击展开后,移动端的 hover 状态会持续触发该规则,菜单无法被 Bootstrap JS 控制收起。 - JS 元素未绑定:HTML 中下拉菜单的触发链接缺失
id="servicesDropdown",内嵌 JS 无法获取目标元素,所有自定义交互逻辑完全失效。 - 交互逻辑矛盾:原 JS 试图让下拉链接点击跳转页面,这和 Bootstrap 默认的点击展开/收起逻辑冲突,且未区分桌面端与移动端的交互差异。
修复步骤
1. 补全 HTML 元素标识
给 Services 下拉菜单的触发链接添加缺失的 id="servicesDropdown":
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" id="servicesDropdown"> Services </a>
2. 调整 CSS 规则
移除移动端强制显示下拉菜单的规则,让 Bootstrap JS 全权控制移动端交互;同时将桌面端 hover 显示规则限定在大屏设备:
/* 删除移动端强制显示的规则 */ /* @media screen and (max-width: 576px) { .dropdown:hover > .dropdown-menu { display: block; margin-top: 0; } } */ /* 仅在桌面端(navbar-expand-lg 断点为992px)启用 hover 展开 */ @media screen and (min-width: 992px) { .dropdown:hover .dropdown-menu { display: block; background-color: hsl(210, 45%, 30%); } #dropdown:hover .dropdown-menu { display: block; } }
3. 优化 JS 交互逻辑
修复元素绑定问题,区分桌面端与移动端交互,添加窗口 resize 监听适配尺寸变化:
<script> const servicesDropdown = document.getElementById('servicesDropdown'); const dropdownMenu = servicesDropdown.nextElementSibling; // 动态更新下拉菜单行为 function updateDropdownBehavior() { const isDesktop = window.matchMedia('(min-width: 992px)').matches; // 先移除所有已绑定事件,避免重复触发 servicesDropdown.removeEventListener('click', handleDropdownClick); servicesDropdown.removeEventListener('mouseenter', handleMouseEnter); servicesDropdown.removeEventListener('mouseleave', handleMouseLeave); dropdownMenu.removeEventListener('mouseleave', handleMouseLeave); if (isDesktop) { // 桌面端:hover 展开/收起,点击跳转服务页面 servicesDropdown.addEventListener('mouseenter', handleMouseEnter); servicesDropdown.addEventListener('mouseleave', handleMouseLeave); dropdownMenu.addEventListener('mouseleave', handleMouseLeave); servicesDropdown.addEventListener('click', function(e) { e.preventDefault(); window.location.href = '/Bootstrap-/services.html'; // 替换为实际服务页面地址 }); } else { // 移动端:保留 Bootstrap 原生点击展开/收起逻辑 servicesDropdown.addEventListener('click', handleDropdownClick); } } // 鼠标进入展开菜单 function handleMouseEnter() { servicesDropdown.setAttribute('aria-expanded', 'true'); dropdownMenu.classList.add('show'); } // 鼠标离开收起菜单 function handleMouseLeave() { servicesDropdown.setAttribute('aria-expanded', 'false'); dropdownMenu.classList.remove('show'); } // 移动端点击切换菜单状态 function handleDropdownClick(e) { e.preventDefault(); const isExpanded = servicesDropdown.getAttribute('aria-expanded') === 'true'; servicesDropdown.setAttribute('aria-expanded', !isExpanded); dropdownMenu.classList.toggle('show', !isExpanded); } // 初始化及窗口尺寸变化时更新行为 updateDropdownBehavior(); window.addEventListener('resize', updateDropdownBehavior); </script>
4. 清理冗余资源
移除重复引入的 Font Awesome 样式链接,减少资源加载:
<!-- 移除以下重复的样式链接 --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
最终效果
- 桌面端:鼠标悬停展开下拉菜单,点击 Services 链接跳转至服务页面
- 移动端:点击 Services 按钮展开菜单,再次点击收起,符合原生交互逻辑
内容的提问来源于stack exchange,提问作者PFL
相关产品推荐
相关产品推荐

