You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

移动端导航点击时的滑出动画失效问题求助

移动端导航点击时的滑出动画失效问题求助

嘿,我看了你的问题和代码,发现问题出在keyframes动画的触发逻辑和类切换的方式上。你现在通过切换openclose两个类来分别触发进入和退出动画,但这里有个容易踩的小坑:当你移除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

火山引擎 最新活动