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(); }); });
逻辑说明
- 首列切换时,先清空末列所有激活面板,再根据中列当前默认选中项激活对应末列内容,彻底避免叠加
- 悬停交互通过监听
mouseenter事件,手动调用Bootstrap Tab的show()方法实现,同时移除data-bs-toggle属性避免冲突
内容的提问来源于stack exchange,提问作者scribbles
相关产品推荐
相关产品推荐

