手风琴菜单是后台与官网的常客,但 90% 的实现依赖第三方库或 CSS Transition。今天原生 JS 手写一条「高度动画 + 状态机」的完整链路,打造丝滑手风琴效果。
效果预览
一、核心思路
- 高度动画:把 height: 0 ↔ 实际高度 交给逐帧函数 createAnimation
- 状态机:用自定义属性 status=”closed|opened|playing” 避免并发点击
- 复用:任意html代码结构插上即用,零配置
二、代码速览
1.动画引擎(animate.js)
实现从一个初始值到目标值的平滑过渡效果,每帧更新一次视图。
函数参数(配置项)
- from:动画起始值(如初始位置、初始透明度等)
- to:动画目标值(最终要达到的数值)
- totalMS:动画总时长(默认 300 毫秒,即 0.3 秒)
- onmove:每帧更新时的回调函数(接收当前动画值,用于实时更新视图,列如 DOM 位置、样式等)
- onend:动画结束时的回调函数(可选,动画完成后执行)
2.交互逻辑(index.js)
关键设计思路
- 用 status 属性(closed/opened/playing)管理子菜单状态,避免动画过程中重复触发点击事件
- 子菜单高度通过 “选项数量 × 单个高度” 动态计算,适配不同数量的子菜单
- 点击新菜单时自动关闭已打开的菜单,保证同一时间只有一个子菜单处于展开状态
3.样式骨架
<ul class="menu-container">
<li class="menu">
<h2>菜单1</h2>
<ul class="submenu">
<li>菜单1</li>
<li>菜单2</li>
<li>菜单3</li>
<li>菜单4</li>
</ul>
</li>
<li class="menu">
<h2>菜单2</h2>
<ul class="submenu">
<li>菜单1</li>
<li>菜单2</li>
<li>菜单3</li>
<li>菜单4</li>
</ul>
</li>
<li class="menu">
<h2>菜单3</h2>
<ul class="submenu">
<li>菜单1</li>
<li>菜单2</li>
<li>菜单3</li>
<li>菜单4</li>
</ul>
</li>
</ul>
三、状态机流程图
总结
高度动画 + 状态机 + 事件委托,让手风琴在任何项目里「开箱即合」。
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END
暂无评论内容