React中onTransitionEnd未触发,汉堡菜单关闭后无法延迟卸载求助
问题原因与解决方案
核心问题:你用的是CSS @keyframes 动画,但绑定的是onTransitionEnd事件——这个事件只监听CSS transition属性的结束,对animation完全无效,所以函数不会触发。
下面给两种可行的解决思路:
思路一:改用CSS Transition实现动画(更推荐)
Transition更适合这种"状态切换"的滑入滑出,代码更简洁,也能完美触发onTransitionEnd。
修改SCSS代码
把原来的animation逻辑换成transition:
.bar{ position: absolute; height: 100%; width: 30em; top: 0px; background-color: rgba(0,0,0,0.7); padding-left: 7em; right: -30em; /* 默认处于滑出状态 */ transition: right 0.3s ease; /* 监听right属性的过渡动画 */ } /* 激活时切换到滑入位置 */ .active { right: 0; } .hide{ display: none; }
修改React组件代码
调整className的逻辑,同时保留原有的状态控制:
import React, { useEffect, useState } from 'react' import Link from 'next/link'; import styles from './BurgerBar.module.scss'; export type BurgerBarProps = { active: boolean } const BurgerBar: React.FC<BurgerBarProps> = ({active}) => { const [hide, setHide] = useState(true); useEffect(() => { handleTransitionEnd(false); }, [active]); function handleTransitionEnd(callFromTransition:boolean) { console.log('FromTransition: ' + callFromTransition); if(active === false && callFromTransition === true){ setHide(true); } if (active === true) { setHide(false); } } return ( <div className={`${styles.bar} ${active ? styles.active : ''} ${hide ? styles.hide : ''}`} onTransitionEnd={() => handleTransitionEnd(true)} > <ul className={styles.listTitle}> <li> <Link href='/projet' className={styles.title}> <img src="/icons/laptop.png" alt="laptop" className={styles.iconTitle}/> PROJETS </Link> </li> {/* 其他菜单项 */} </ul> </div> ) } export default BurgerBar;
思路二:坚持用Animation,改用onAnimationEnd事件
如果一定要保留@keyframes动画,把监听事件换成onAnimationEnd,同时可以判断具体是哪个动画结束(避免滑入动画触发不必要的逻辑):
修改React组件的div部分
<div className={`${styles.bar} ${active ? '' : styles.desactive} ${hide ? styles.hide : ''}`} onAnimationEnd={(e) => { // 只在滑出动画结束时执行逻辑 if (e.animationName === 'slide-out') { handleTransitionEnd(true); } }} >
注意事项
- 部分浏览器可能会给animationName加前缀(比如webkitAnimationName),可以用
e.animationName.includes('slide-out')来兼容。 - 确保在动画完全结束后再设置
hide类(display:none),否则会直接中断动画,导致事件不触发。
内容的提问来源于stack exchange,提问作者Malaury Boudon
相关产品推荐
相关产品推荐

