CSS+TypeScript移动端菜单侧滑动画:关闭无动画问题求助
移动端菜单关闭动画不生效的解决思路
问题根源
你当前的实现中,关闭菜单时通过isMobileMenuOpen &&直接移除了菜单内的<ul>元素,同时切换dismiss类触发动画。但元素内容被立即移除,导致动画还未执行完成就失去了载体,所以关闭动画直接跳转到结束状态。另外,外层按钮嵌套内层按钮的HTML结构是无效的,可能会干扰点击事件和渲染逻辑。
具体解决步骤
移除无效的按钮嵌套结构
把内层的<button>替换为直接渲染图标,避免HTML语义错误:{/* Mobile Menu */} <div className="lg:hidden"> <button className="flex items-center w-8" onClick={toggleMenu}> {isMobileMenuOpen ? <AiOutlineUp className="w-full h-full" /> : <AiOutlineDown className="w-full h-full" /> } </button> </div>保留菜单DOM结构,不通过条件渲染移除内容
始终渲染菜单内的<ul>,用CSS类控制动画和可见性,而不是直接删除元素:{/* Mobile Menu Items */} <div className={`mobileMenu lg:hidden p-10 bg-[#101010] ${ isMobileMenuOpen ? "selected" : "dismiss" }`} > <ul className="flex flex-col gap-4 text-[22px]"> {renderNavLinks(navLinks)} </ul> </div>调整CSS动画逻辑,确保关闭动画有完整执行周期
优化关键帧动画的触发逻辑,让菜单在基础状态下保持可动画的属性:@keyframes slidein { from { transform: translateY(-100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } } @keyframes slideout { from { transform: translateY(0); opacity: 1; } to { transform: translateY(-100%); opacity: 0; } } .mobileMenu { transform: translateY(-100%); opacity: 0; overflow: hidden; } .mobileMenu.selected { animation: slidein 0.3s forwards; } .mobileMenu.dismiss { animation: slideout 0.3s forwards; }监听动画结束事件,控制最终隐藏状态
如果需要动画结束后完全隐藏菜单(比如设置display: none),可以通过animationend事件延迟处理:import { useState } from 'react'; const [isMenuHidden, setIsMenuHidden] = useState(true); const toggleMenu = () => { if (isMobileMenuOpen) { // 关闭菜单时先显示元素,触发动画 setIsMenuHidden(false); setIsMobileMenuOpen(false); } else { setIsMobileMenuOpen(true); setIsMenuHidden(false); } }; const handleAnimationEnd = (e: AnimationEvent) => { if (e.animationName === 'slideout' && !isMobileMenuOpen) { // 动画结束后隐藏元素 setIsMenuHidden(true); } }; // 菜单元素修改 <div className={`mobileMenu lg:hidden p-10 bg-[#101010] ${ isMobileMenuOpen ? "selected" : "dismiss" } ${isMenuHidden ? 'hidden' : ''}`} onAnimationEnd={handleAnimationEnd} > <ul className="flex flex-col gap-4 text-[22px]"> {renderNavLinks(navLinks)} </ul> </div>改用CSS Transition替代关键帧(更简洁方案)
如果不需要复杂的关键帧动画,用transition可以更稳定地实现滑入滑出,且无需额外事件监听:.mobileMenu { transform: translateY(-100%); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; overflow: hidden; } .mobileMenu.selected { transform: translateY(0); opacity: 1; } .mobileMenu.dismiss { transform: translateY(-100%); opacity: 0; }
内容的提问来源于stack exchange,提问作者salm00n
相关产品推荐
相关产品推荐

