You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非前端开发者求助:用Bootstrap 4实现导航栏元素逐个折叠(禁用jQuery)

不用jQuery在Bootstrap 4实现响应式逐个折叠侧边栏

Hey there! 我完全懂你作为非前端开发者的困扰——Bootstrap 4默认很多组件都绑着jQuery,要实现这种逐个折叠的侧边栏还不能用它,确实有点卡壳。不过别担心,咱们用原生JS就能搞定,而且完全贴合你要的col-2响应式需求,一步步来:

核心思路

  1. 用Bootstrap的网格系统搭建col-xl-2 col-lg-2的左侧侧边栏,保证响应式尺寸
  2. 抛弃依赖jQuery的data-toggle属性,用原生JS实现菜单的逐个折叠逻辑
  3. 结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:41:50