用事件冒泡实现折叠面板的核心是只给父容器绑定一个click事件,通过event.target判断点击标题并切换对应内容区显示状态;结构用语义化HTML,JS通过closest定位面板、querySelector找内容区,用classList.toggle('active')配合CSS的max-height过渡实现平滑展开收起,支持单开时先关闭所有再展开目标。

用事件冒泡实现折叠面板,核心是:**只给父容器绑定一个 click 事件,通过 event.target 判断点击的是哪个标题,再切换对应内容区的显示状态**。这样避免给每个标题单独绑事件,代码更简洁、动态增删面板项也无需重新绑定。
结构准备:语义化 HTML
确保面板结构清晰,标题和内容有明确的父子/相邻关系。推荐用 <details><summary></summary></details> 是原生方案,但若需自定义样式或兼容性控制,可用如下结构:
<div class="accordion">
<div class="panel">
<h3 class="panel-title">标题一</h3>
<div class="panel-content">内容一...</div>
</div>
<div class="panel">
<h3 class="panel-title">标题二</h3>
<div class="panel-content">内容二...</div>
</div>
</div>
利用事件冒泡统一监听
给外层 .accordion 绑定 click,检查 event.target 是否为某个 .panel-title。是则找到它所在的 .panel,再定位其内部的 .panel-content 进行切换:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
document.querySelector('.accordion').addEventListener('click', function (e) {
if (e.target.classList.contains('panel-title')) {
const panel = e.target.closest('.panel');
const content = panel.querySelector('.panel-content');
<pre class="brush:php;toolbar:false;">// 切换展开/收起(可配合 class 控制 CSS 过渡)
content.classList.toggle('active');} });
-
e.target.closest('.panel')向上查找最近的面板容器,确保即使点击标题内嵌元素(如 span、图标)也能准确定位 - 用
classList.toggle('active')而非手动设display,便于用 CSS 实现过渡动画 - 不直接操作
style.display,保持样式与行为分离
CSS 配合实现平滑展开收起
仅靠 JS 切换 class,视觉效果由 CSS 完成。关键点:用 max-height + overflow: hidden 实现过渡,避免 height: auto 无法过渡的问题:
.panel-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, padding 0.3s ease-out;
}
<p>.panel-content.active {
max-height: 500px; /<em> 设为足够大的值,或用 JS 动态计算 </em>/
padding: 1rem;
}
</p>
- 如果内容高度差异大,可改用 JS 动态读取
scrollHeight并赋给max-height,实现精准过渡 - 收起时 padding 也要参与过渡,否则视觉突兀
- 加
overflow: hidden防止内容溢出影响布局
进阶:支持单开(关闭其他面板)
若需手风琴效果(一次只展开一个),在切换前先关闭所有已展开的 .panel-content:
document.querySelector('.accordion').addEventListener('click', function (e) {
if (e.target.classList.contains('panel-title')) {
// 先收起所有
document.querySelectorAll('.panel-content.active').forEach(el => {
el.classList.remove('active');
});
<pre class="brush:php;toolbar:false;">// 再展开当前
const panel = e.target.closest('.panel');
const content = panel.querySelector('.panel-content');
content.classList.add('active');} });
- 注意顺序:先统一收起,再展开目标,避免自身也被清除
- 用
querySelectorAll('.panel-content.active')精准筛选,不影响未激活项
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










