非前端开发者求助:用Bootstrap 4实现导航栏元素逐个折叠(禁用jQuery)
不用jQuery在Bootstrap 4实现响应式逐个折叠侧边栏
Hey there! 我完全懂你作为非前端开发者的困扰——Bootstrap 4默认很多组件都绑着jQuery,要实现这种逐个折叠的侧边栏还不能用它,确实有点卡壳。不过别担心,咱们用原生JS就能搞定,而且完全贴合你要的col-2响应式需求,一步步来:
核心思路
- 用Bootstrap的网格系统搭建
col-xl-2 col-lg-2的左侧侧边栏,保证响应式尺寸 - 抛弃依赖jQuery的
data-toggle属性,用原生JS实现菜单的逐个折叠逻辑 - 结合CSS媒体查询+JS窗口监听,实现不同分辨率下的菜单显示规则
完整代码示例
HTML结构
<div class="container-fluid"> <div class="row"> <!-- 左侧响应式侧边栏(col-2) --> <nav class="col-xl-2 col-lg-2 bg-light sidebar"> <div class="sidebar-sticky py-3"> <ul class="nav flex-column"> <!-- 可折叠菜单项1 --> <li class="nav-item mb-2"> <a class="nav-link menu-toggle text-dark" href="#menu1" role="button"> 主菜单1 </a> <div class="collapse menu-content" id="menu1"> <ul class="nav flex-column pl-4"> <li class="nav-item"><a class="nav-link small" href="#">子项1-1</a></li> <li class="nav-item"><a class="nav-link small" href="#">子项1-2</a></li> </ul> </div> </li> <!-- 可折叠菜单项2 --> <li class="nav-item mb-2"> <a class="nav-link menu-toggle text-dark" href="#menu2" role="button"> 主菜单2 </a> <div class="collapse menu-content" id="menu2"> <ul class="nav flex-column pl-4"> <li class="nav-item"><a class="nav-link small" href="#">子项2-1</a></li> <li class="nav-item"><a class="nav-link small" href="#">子项2-2</a></li> <li class="nav-item"><a class="nav-link small" href="#">子项2-3</a></li> </ul> </div> </li> <!-- Large屏始终显示的菜单项 --> <li class="nav-item mb-2"> <a class="nav-link menu-toggle text-dark" href="#menu3" role="button"> 主菜单3(Large屏常驻) </a> <div class="collapse menu-content always-show-lg" id="menu3"> <ul class="nav flex-column pl-4"> <li class="nav-item"><a class="nav-link small" href="#">子项3-1</a></li> </ul> </div> </li> </ul> </div> </nav> <!-- 右侧主内容区 --> <main class="col-xl-10 col-lg-10 p-4"> <h1>主内容区域</h1> <p>这里是你的应用内容</p> </main> </div> </div>
CSS样式(处理响应式显示)
/* 基础侧边栏样式优化 */ .sidebar { min-height: 100vh; border-right: 1px solid #eee; } .menu-toggle { cursor: pointer; } /* XL屏(≥1200px):所有菜单强制展开,禁用点击 */ @media (min-width: 1200px) { .sidebar .menu-content { display: block !important; } .sidebar .menu-toggle { cursor: default; } } /* Large屏(992px-1199px):指定菜单始终展开 */ @media (min-width: 992px) and (max-width: 1199px) { .sidebar .always-show-lg { display: block !important; } }
原生JS逻辑(实现折叠+响应式适配)
document.addEventListener('DOMContentLoaded', function() { // 获取所有菜单触发按钮 const menuToggles = document.querySelectorAll('.menu-toggle'); // 给每个触发按钮绑定点击事件 menuToggles.forEach(toggle => { toggle.addEventListener('click', function(e) { e.preventDefault(); // 阻止href的默认跳转行为 // 获取当前要切换的菜单ID const targetMenuId = this.getAttribute('href').slice(1); const targetMenu = document.getElementById(targetMenuId); // 关闭其他所有展开的菜单(实现逐个折叠) document.querySelectorAll('.menu-content.show').forEach(menu => { if (menu.id !== targetMenuId) { menu.classList.remove('show'); } }); // 切换当前菜单的展开/收起状态 targetMenu.classList.toggle('show'); }); }); // 监听窗口大小变化,动态调整菜单状态 function adjustMenuState() { const windowWidth = window.innerWidth; const allMenus = document.querySelectorAll('.menu-content'); if (windowWidth >= 1200) { // XL屏:所有菜单展开 allMenus.forEach(menu => menu.classList.add('show')); } else if (windowWidth >= 992 && windowWidth < 1200) { // Large屏:仅保留always-show-lg的菜单展开,其他收起 allMenus.forEach(menu => { if (menu.classList.contains('always-show-lg')) { menu.classList.add('show'); } else { menu.classList.remove('show'); } }); } else { // 更小屏幕:默认全部收起(可根据需求调整) allMenus.forEach(menu => menu.classList.remove('show')); } } // 初始化时执行一次,确保菜单状态正确 adjustMenuState(); // 窗口大小变化时重新调整 window.addEventListener('resize', adjustMenuState); });
关键细节说明
- 无jQuery依赖:完全用原生
addEventListener和DOM操作实现折叠逻辑,替代Bootstrap默认的jQuery驱动组件 - 逐个折叠效果:点击某一菜单时,先关闭其他所有展开的子菜单,再切换当前菜单状态,保证同一时间只有一个子菜单展开
- 响应式适配:严格遵循你要求的
col-2尺寸,通过媒体查询和JS监听,实现XL屏全显示、Large屏指定菜单显示的规则 - 可扩展性:如果需要修改“Large屏始终显示”的菜单,只需要给对应的
menu-content加上always-show-lg类即可
内容的提问来源于stack exchange,提问作者Macryo
相关产品推荐
相关产品推荐

