移动端导航点击时的滑出动画失效问题求助
移动端导航点击时的滑出动画失效问题求助
嘿,我看了你的问题和代码,发现问题出在keyframes动画的触发逻辑和类切换的方式上。你现在通过切换open和close两个类来分别触发进入和退出动画,但这里有个容易踩的小坑:当你移除open类的瞬间,元素的动画状态会立刻回到初始值,紧接着添加close类时,浏览器可能来不及捕捉状态变化,导致退出动画直接“跳过”了。
问题根源拆解
- 你的
slideDown动画用了forwards,所以open类生效时,元素会保持translateY(0)的状态;但一旦移除open类,这个动画的状态就失效了,元素会立刻回到.mobile-nav默认的无transform状态(相当于translateY(0))。 - 这时候你马上添加
close类,slideUp动画的起始状态和元素当前状态完全一致,浏览器会认为没有样式变化,自然不会播放动画。
解决方案(推荐用更简洁的Transition方案)
相比keyframes,CSS Transition更适合这种简单的状态切换场景,逻辑更清晰也不容易出问题:
1. 修改CSS代码
.mobile-nav { display: block; width: 100%; background-color: var(--neutral-1000); z-index: 1000; position: absolute; top: 0; left: 0; /* 默认隐藏在视口上方 */ transform: translateY(-100%); /* 添加过渡动画,监听transform变化 */ transition: transform 0.3s ease; } /* 只需要一个open类控制显示状态 */ .mobile-nav.open { transform: translateY(0); }
2. 简化JS代码
不用再切换close类,直接通过toggle切换open类即可:
document.addEventListener("DOMContentLoaded", function () { const hamburgerMenu = document.getElementById("hamburger-menu"); const mobileNav = document.querySelector(".mobile-nav"); const menuIcon = document.getElementById("menu-icon"); hamburgerMenu.addEventListener("click", function () { // 直接切换open类,自动触发过渡动画 mobileNav.classList.toggle("open"); // 切换图标 menuIcon.src = mobileNav.classList.contains("open") ? "/media/cross_nav.svg" : "/media/hamburger_nav.svg"; }); });
如果你坚持用Keyframes的修复方案
如果一定要保留原有keyframes动画,可以通过给类切换加个微小延迟,让浏览器有时间处理样式更新:
document.addEventListener("DOMContentLoaded", function () { const hamburgerMenu = document.getElementById("hamburger-menu"); const mobileNav = document.querySelector(".mobile-nav"); const menuIcon = document.getElementById("menu-icon"); hamburgerMenu.addEventListener("click", function () { if (mobileNav.classList.contains("open")) { mobileNav.classList.remove("open"); // 加0ms延迟,让浏览器先处理移除open类的样式变化 setTimeout(() => { mobileNav.classList.add("close"); }, 0); } else { mobileNav.classList.remove("close"); mobileNav.classList.add("open"); } menuIcon.src = mobileNav.classList.contains("open") ? "/media/cross_nav.svg" : "/media/hamburger_nav.svg"; }); });
不过这种方法不如Transition优雅,还可能存在浏览器兼容性隐患,所以更推荐第一种方案。
另外提个小细节:你的汉堡按钮是放在.mobile-nav里面的,当导航向上滑出时,按钮也会跟着离开视口,虽然当前点击能触发,但体验不太友好,建议把汉堡按钮移到.mobile-nav外面,和logo同级放在header里,这样用户随时都能点击操作~
备注:内容来源于stack exchange,提问作者EviVermeeren




