
本文介绍如何纯使用 bootstrap 5 内置 collapse 组件,无需自定义 javascript,即可实现两个图表的互斥显示(点击按钮仅显示其对应图表)、以及一个“隐藏当前图表”的全局控制功能。
本文介绍如何纯使用 bootstrap 5 内置 collapse 组件,无需自定义 javascript,即可实现两个图表的互斥显示(点击按钮仅显示其对应图表)、以及一个“隐藏当前图表”的全局控制功能。
在 Bootstrap 5 中,Collapse 组件原生支持基于 data-bs-toggle="collapse" 的声明式交互,但默认行为是“独立触发”——即每个按钮仅控制其绑定的目标元素,无法自动确保多个 Collapse 元素互斥显示(即“单选”效果)。要实现“点击 Emotions 按钮时隐藏 Polarity 图表、反之亦然”,同时让 Hide 按钮仅关闭当前可见图表(而非切换状态),关键在于利用 Bootstrap 的嵌套 Collapse 机制与 .show 类的初始状态控制。
✅ 推荐方案:纯 Bootstrap 声明式实现(零 JS)
核心思路是:将两个图表容器包裹在一个外层 Collapse 容器中,并通过 radio 按钮 + 外层 Collapse 控制开关,结合内层 Collapse 的初始 .show 状态,触发 Bootstrap 的内置互斥逻辑。
<!-- 控制按钮组:使用 radio 实现单选语义 -->
<div class="btn-group" role="group">
<input type="radio" class="btn-check" name="chart-toggle" id="emotions-radio" autocomplete="off" checked data-bs-toggle="collapse" data-bs-target=".multi-collapse"><label class="btn btn-outline-primary" for="emotions-radio">Emotions</label>
<input type="radio" class="btn-check" name="chart-toggle" id="polarity-radio" autocomplete="off" data-bs-toggle="collapse" data-bs-target=".multi-collapse"><label class="btn btn-outline-primary" for="polarity-radio">Polarity</label>
<!-- Hide 按钮:仅控制外层 Collapse,不干扰内层状态 -->
<input type="checkbox" class="btn-check" id="hide-checkbox" autocomplete="off" data-bs-toggle="collapse" data-bs-target="#chart-wrapper"><label class="btn btn-outline-danger" for="hide-checkbox">Hide</label>
</div>
<!-- 外层 Collapse 容器(用于 Hide 按钮统一控制) -->
<div id="chart-wrapper" class="collapse show mt-3">
<div class="row">
<!-- 内层 Collapse:第一个加 .show,第二个不加,Bootstrap 自动处理互斥 -->
<div class="col">
<div class="multi-collapse collapse show">
<div class="card card-body">
Emotions Chart Placeholder
</div>
</div>
</div>
<div class="col">
<div class="multi-collapse collapse">
<div class="card card-body">
Polarity Chart Placeholder
</div>
</div>
</div>
</div>
</div>
✅ 为什么有效?
- Bootstrap 的 Collapse 在检测到同一 data-bs-target(如 .multi-collapse)被多个触发器调用时,会自动管理 .show 类的流转:激活一个时,自动移除其他同 target 元素的 .show。
- 外层 #chart-wrapper 的 .collapse.show 初始为展开态;Hide 按钮通过 data-bs-target="#chart-wrapper" 控制它,实现“一键收起全部”,且不影响内层 .multi-collapse 的互斥逻辑。
- 所有动画均由 Bootstrap CSS 过渡完成(transition: height .35s ease),无需手动操作 DOM 或 class。
⚠️ 注意事项与常见误区
- 不要移除 data-bs-target:你观察到“移除后动画消失”是正确的——data-bs-target 是 Bootstrap 初始化 Collapse 实例并绑定事件监听器的必要属性。没有它,组件无法识别目标,退化为静态 HTML。
- .show 类必须显式添加:Bootstrap 不会自动为首个 Collapse 添加 .show;若遗漏,所有图表默认隐藏,首次点击无响应。
- 避免混用 JS 手动 toggle:如原文中直接 classList.add/remove("show"),会跳过 Bootstrap 的动画队列和事件(如 shown.bs.collapse),导致动画中断或事件监听失效。应优先使用声明式方式,或严格调用 bootstrap.Collapse.getInstance(el).show() / .hide() 方法。
- 语义化增强:使用 而非
✅ 补充:需要 JS 动态控制时的正确姿势
若业务逻辑复杂(如按顺序轮播图表、条件触发等),仍需 JavaScript,请务必使用 Bootstrap 提供的实例方法:
const collapse1 = bootstrap.Collapse.getOrCreateInstance('#multiCollapseExample1');
const collapse2 = bootstrap.Collapse.getOrCreateInstance('#multiCollapseExample2');
// 正确:触发完整生命周期(动画 + 事件)
document.getElementById('emotions-btn').addEventListener('click', () => {
collapse1.show();
collapse2.hide(); // 自动等待 collapse1 动画结束再执行
});
document.getElementById('hide-btn').addEventListener('click', () => {
// 隐藏当前活跃的图表(可扩展判断逻辑)
if (collapse1._isShown) collapse1.hide();
else if (collapse2._isShown) collapse2.hide();
});
? 小结:Bootstrap 的 Collapse 组件设计精巧,善用其 data-bs-target、.show 初始类、以及嵌套结构,即可优雅实现复杂交互。优先声明式,慎用直接 DOM 操作——这是保障动画流畅性与可维护性的关键。











