网站首页 > 技术文章 正文
手风琴菜单是后台与官网的常客,但 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>
三、状态机流程图
总结
高度动画 + 状态机 + 事件委托,让手风琴在任何项目里「开箱即合」。
- 上一篇: 我试了一周的《氛围编程》,这是我的感受
- 下一篇: JS 打造「放大镜 + 缩略图」一体组件
猜你喜欢
- 2025-09-23 Github开源即时通讯(IM)项目,可实现聊天、语音通话等
- 2025-09-23 Astra 横空出世,真的是 JS 转 EXE 的未来吗?
- 2025-09-23 万字长文帮你彻底搞懂JS中的Promise
- 2025-09-23 JS中 call()、apply()、bind() 的用法
- 2025-09-23 JS 克隆对象八种技术,为何少不了 StructuredClone?
- 2025-09-23 为什么 JS 开发者更喜欢 Axios 而不是 Fetch?
- 2025-09-23 JS 高手进阶:玩转七种继承艺术_js继承是什么意思
- 2025-09-23 JS 打造「放大镜 + 缩略图」一体组件
- 2024-12-18 比较 JavaScript 对象的四种方式「实践」
- 2024-12-18 我不知道还可以用 JS 做的 6 件事
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)