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

Bootstrap 5三级联动导航求助:首列切换时末列内容叠加异常

问题

我想用Bootstrap 5做一个三列联动导航:

  • 首列包含导航列表
  • 中列根据首列激活项显示对应导航列表
  • 末列显示中列当前激活项的对应内容
    最终要嵌入到巨型菜单里,理想状态是完全通过鼠标悬停而非点击交互。

我已经完成基础代码,但切换首列第二、三项(比如First Col #2 > Middle Col #2_1)时,末列内容会叠加在之前内容的下方。我推测需要编写JavaScript脚本,在用户操作首列选项时隐藏末列的激活项,但自己JavaScript能力不足,求帮助。

基础代码如下:

<div class="container py-8 text-center">
  <div class="row">
    
      <div class="col-4">
          <!-- First Column List -->
          <ul class="nav nav-tabs nav-tabs-basic flex-column">
              <li class="nav-item"> 
                  <a class="nav-link active" data-bs-toggle="tab" href="#first-1-1">First Col #1</a> 
              </li>
              <li class="nav-item"> 
                  <a class="nav-link" data-bs-toggle="tab" href="#first-1-2">First Col #2</a> 
              </li>
              <li class="nav-item"> 
                  <a class="nav-link" data-bs-toggle="tab" href="#first-1-3">First Col #3</a> 
            </li>
          </ul><!-- /.nav-tabs -->
      </div>
    
      <div class="col-4">
          <!-- Middle Column List -->
          <div class="tab-content mt-0">
              <div class="tab-pane fade show active" id="first-1-1">
                  <ul class="nav nav-tabs nav-tabs-basic flex-column">
                      <li class="nav-item"> 
                          <a class="nav-link active" data-bs-toggle="tab" href="#middle-1-1">Middle Col #1_1</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-1-2">Middle Col #1_2</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-1-3">Middle Col #1_3</a> 
                      </li>
                  </ul><!-- /.nav-tabs -->
              </div><!--/.tab-pane -->
              <div class="tab-pane fade" id="first-1-2">
                  <ul class="nav nav-tabs nav-tabs-basic flex-column">
                      <li class="nav-item"> 
                          <a class="nav-link active" data-bs-toggle="tab" href="#middle-2-1">Middle Col #2_1</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-2-2">Middle Col #2_2</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-2-3">Middle Col #2_3</a> 
                      </li>
                  </ul><!-- /.nav-tabs -->
              </div><!--/.tab-pane -->
              <div class="tab-pane fade" id="first-1-3">
                  <ul class="nav nav-tabs nav-tabs-basic flex-column">
                      <li class="nav-item"> 
                          <a class="nav-link active" data-bs-toggle="tab" href="#middle-3-1">Middle Col #3_1</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-3-2">Middle Col #3_2</a> 
                      </li>
                      <li class="nav-item"> 
                          <a class="nav-link" data-bs-toggle="tab" href="#middle-3-3">Middle Col #3_3</a> 
                      </li>
                  </ul><!-- /.nav-tabs -->
              </div><!--/.tab-pane -->
          </div><!-- /.tab-content -->
      </div><!--/column -->

      <div class="col-4">
          <!-- Last Column Items -->
          <div class="tab-content mt-0">
              <div class="tab-pane fade show active" id="middle-1-1">
                  <p>Last Col #1_1_1</p>
              </div>
              <div class="tab-pane fade" id="middle-1-2">
                  <p>Last Col #1_2_1</p>
              </div>
              <div class="tab-pane fade" id="middle-1-3">
                  <p>Last Col #1_3_1</p>
              </div>
              <div class="tab-pane fade" id="middle-2-1">
                  <p>Last Col #2_1_1</p>
              </div>
              <div class="tab-pane fade" id="middle-2-2">
                  <p>Last Col #2_2_1</p>
              </div>
              <div class="tab-pane fade" id="middle-2-3">
                  <p>Last Col #2_3_1</p>
              </div>
              <div class="tab-pane fade" id="middle-3-1">
                  <p>Last Col #3_1_1</p>
              </div>
              <div class="tab-pane fade" id="middle-3-2">
                  <p>Last Col #3_2_1</p>
              </div>
              <div class="tab-pane fade" id="middle-3-3">
                  <p>Last Col #3_3_1</p>
              </div>
          </div><!-- /.tab-content -->
      </div><!--/column -->
    
  </div><!--/row -->
</div><!--/container -->

解决方案

问题根源

Bootstrap的Tab组件默认只关联直接对应的tab-content容器,首列切换时仅控制中列的面板显示,不会自动重置末列的激活状态,导致多个末列面板同时处于激活状态,出现叠加。

修复叠加问题的JavaScript代码

添加以下代码,监听首列Tab的切换事件,清空末列的激活状态,并自动激活当前中列默认选中项对应的末列内容:

// 获取首列所有导航链接
const firstColLinks = document.querySelectorAll('.col-4:first-child .nav-link');
// 获取末列的tab-content容器
const lastColContent = document.querySelector('.col-4:last-child .tab-content');

firstColLinks.forEach(link => {
  link.addEventListener('shown.bs.tab', function() {
    // 隐藏末列所有激活的面板
    lastColContent.querySelectorAll('.tab-pane.show.active').forEach(pane => {
      pane.classList.remove('show', 'active');
    });
    // 获取当前中列激活的导航链接
    const activeMiddleLink = document.querySelector('.col-4:nth-child(2) .nav-link.active');
    if (activeMiddleLink) {
      // 激活对应末列面板
      const targetId = activeMiddleLink.getAttribute('href').slice(1);
      document.getElementById(targetId).classList.add('show', 'active');
    }
  });
});

优化为悬停交互

要实现完全鼠标悬停触发,替换默认点击逻辑,添加以下代码:

// 移除所有导航链接的默认点击切换属性
document.querySelectorAll('.nav-link').forEach(link => {
  link.removeAttribute('data-bs-toggle');
});

// 首列悬停切换
document.querySelectorAll('.col-4:first-child .nav-link').forEach(link => {
  link.addEventListener('mouseenter', function() {
    new bootstrap.Tab(this).show();
  });
});

// 中列悬停切换
document.querySelectorAll('.col-4:nth-child(2) .nav-link').forEach(link => {
  link.addEventListener('mouseenter', function() {
    new bootstrap.Tab(this).show();
  });
});

逻辑说明

  1. 首列切换时,先清空末列所有激活面板,再根据中列当前默认选中项激活对应末列内容,彻底避免叠加
  2. 悬停交互通过监听mouseenter事件,手动调用Bootstrap Tab的show()方法实现,同时移除data-bs-toggle属性避免冲突

内容的提问来源于stack exchange,提问作者scribbles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:47:04