Framer Motion:动画结束后如何设置display为none?
如何在Framer Motion动画结束后设置元素为display: none
临时方案(当前实现)
你当前通过嵌套两层motion.div,外层以延迟切换display属性来匹配内层淡出动画的时长,代码如下:
<motion.div initial={{display:'flex'}} animate={{display:'none'}} transition={{delay:3.3}} > <motion.div initial={{opacity: 1}} animate={{opacity: 0,}} transition={{delay:3, duration: 0.3,}} > {/* 你的组件内容 */} </motion.div> </motion.div>
这个方案可以生效,但手动计算延迟容易出错(比如动画时长修改时需要同步调整延迟时间),以下是两种更优的实现方式:
方案1:利用onAnimationComplete回调
直接在执行淡出动画的motion.div上绑定onAnimationComplete回调,动画结束后通过状态控制外层元素的display属性,无需手动计算延迟:
import { useState } from 'react'; import { motion } from 'framer-motion'; function FadingComponent() { const [isVisible, setIsVisible] = useState(true); return ( <div style={{ display: isVisible ? 'flex' : 'none' }}> <motion.div initial={{ opacity: 1 }} animate={{ opacity: 0 }} transition={{ delay: 3, duration: 0.3 }} onAnimationComplete={() => setIsVisible(false)} > {/* 你的组件内容 */} </motion.div> </div> ); }
方案2:使用AnimatePresence组件(推荐)
Framer Motion的AnimatePresence专门用于处理元素的进入/退出动画,当元素被卸载时会自动播放exit动画,动画结束后元素会被从DOM中移除(效果等同于display: none且更彻底):
import { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; function FadingComponent() { const [isVisible, setIsVisible] = useState(true); // 示例:3秒后触发隐藏逻辑 setTimeout(() => setIsVisible(false), 3000); return ( <AnimatePresence> {isVisible && ( <motion.div initial={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.3 }} style={{ display: 'flex' }} > {/* 你的组件内容 */} </motion.div> )} </AnimatePresence> ); }
方案对比
- 方案1适合需要保留DOM但隐藏元素的场景,仅通过CSS控制显示状态;
- 方案2适合无需保留DOM的场景,动画结束后直接卸载元素,避免无用DOM节点占用资源;
- 两种方案均无需手动同步延迟时间,动画参数修改时无需额外调整,维护性更强。
内容的提问来源于stack exchange,提问作者prog-pog
相关产品推荐
相关产品推荐

