你有没有在浏览网站时,遇到过那种点一下展开内容、再点一下收起来的侧边栏?这种效果很常见,特别是在手机端或者后台管理系统里,它就是“手风琴菜单导航”。名字挺文艺,其实原理很简单,就像手风琴一样,拉开一节,其他自动收缩。
为什么用手风琴菜单?
想象你在一家电商网站后台管理商品分类。一级类目有“家电”、“服饰”、“数码”,每个下面还有一堆二级、三级子类。如果全展开,页面得拉半天才能到底。这时候手风琴菜单就派上用场了——点击“家电”,展开它的子项,再点“数码”,“家电”自动合上。视觉清爽,操作也顺手。
基本结构怎么写?
实现这个效果,HTML 结构通常是一个无序列表,每一项包含一个标题和一个内容块。用 CSS 控制显示隐藏,再加点 JavaScript 做交互。
<ul class="accordion">
<li>
<div class="accordion-header">家电</div>
<div class="accordion-body" style="display: none;">
<ul>
<li>电视</li>
<li>冰箱</li>
<li>洗衣机</li>
</ul>
</div>
</li>
<li>
<div class="accordion-header">数码</div>
<div class="accordion-body" style="display: none;">
<ul>
<li>手机</li>
<li>耳机</li>
<li>平板</li>
</ul>
</div>
</li>
</ul>
让菜单动起来
光有结构还不行,得让它能点开合上。JavaScript 监听点击事件就行。每次点击标题,先关掉所有已经展开的面板,再打开当前的。
document.querySelectorAll('.accordion-header').forEach(header => {
header.addEventListener('click', function() {
const body = this.nextElementSibling;
document.querySelectorAll('.accordion-body').forEach(panel => {
if (panel !== body) {
panel.style.display = 'none';
}
});
if (body.style.display === 'block') {
body.style.display = 'none';
} else {
body.style.display = 'block';
}
});
});
加点动画更顺滑
直接显隐太生硬,用户会觉得“跳”。可以改用 max-height 控制,配合 CSS 过渡,做出缓缓展开的效果。
.accordion-body {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.accordion-body.open {
max-height: 200px; /* 根据实际内容调整 */
}
对应的 JS 改成切换 class:
if (body.classList.contains('open')) {
body.classList.remove('open');
} else {
// 先关闭其他
document.querySelectorAll('.accordion-body').forEach(b => b.classList.remove('open'));
body.classList.add('open');
}
实际应用场景
除了后台菜单,这种交互也常用于 FAQ 页面。比如用户问“怎么重装系统?”、“驱动怎么装?”,每个问题当做一个手风琴项,点开看答案,不用跳转页面,体验更连贯。
现在很多前端框架像 Vue、React 都有现成的组件库,比如 Element Plus 或 Ant Design,直接调用 Accordion 组件就能用,省得从头写。但了解底层实现,改样式、调逻辑的时候才不会抓瞎。