You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:43:19