如何实现Div元素入场与退场双动画?退场动画失效排查
解决汉堡菜单退场动画不生效的问题
问题分析
入场动画生效但退场动画无效果,核心原因通常有两个:
- 入场动画使用
both值,会让元素在动画结束后保持最终状态,但切换退场类时,浏览器因DOM状态变化过快,无法正确触发反向动画。 - 若切换退场类的同时直接设置
display: none或类似隐藏属性,会导致动画未执行就被隐藏,自然看不到效果。
修复方案
1. 调整CSS动画逻辑
明确基础状态与动画的关系,用forwards替代both,确保动画结束后保持目标状态:
/* 菜单基础样式(默认处于退场后的隐藏状态) */ .Hamburger-Menu { opacity: 0; transform: scaleX(0); transform-origin: right center; } /* 入场动画:从隐藏到显示 */ .Hamburger-Menu-Opened { animation: scale-in-hor-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) forwards; } /* 退场动画:从显示到隐藏 */ .Hamburger-Menu-Closed { animation: scale-out-hor-right 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) forwards; } /* 确保关键帧正确定义(Animista导出的关键帧需保留) */ @keyframes scale-in-hor-right { 0% { transform: scaleX(0); opacity: 0; } 100% { transform: scaleX(1); opacity: 1; } } @keyframes scale-out-hor-right { 0% { transform: scaleX(1); opacity: 1; } 100% { transform: scaleX(0); opacity: 0; } }
2. 优化JS切换逻辑
通过强制重绘和动画结束事件,保证动画完整执行:
const menu = document.querySelector('.Hamburger-Menu'); const toggleBtn = document.querySelector('.toggle-btn'); // 你的红色方块按钮 toggleBtn.addEventListener('click', () => { // 先移除所有动画类,触发浏览器重绘 menu.classList.remove('Hamburger-Menu-Opened', 'Hamburger-Menu-Closed'); void menu.offsetWidth; // 强制重绘,确保新动画能被触发 if (menu.classList.contains('is-visible')) { // 执行退场动画,结束后标记为隐藏 menu.classList.add('Hamburger-Menu-Closed'); menu.addEventListener('animationend', () => { menu.classList.remove('is-visible'); }, { once: true }); } else { // 执行入场动画,先标记为可见 menu.classList.add('is-visible'); menu.classList.add('Hamburger-Menu-Opened'); } });
关键注意点
- 用
is-visible类标记菜单的可见状态,避免动画类与状态类混淆。 void menu.offsetWidth强制浏览器重绘,解决类切换过快导致的动画不触发问题。- 通过
animationend事件在退场动画结束后再修改可见状态,保证动画完整播放。
内容的提问来源于stack exchange,提问作者user11270788
相关产品推荐
相关产品推荐

