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

CSS+JS实现顺序淡入淡出动画时淡出效果不显示求助

解决顺序淡入淡出动画中淡出效果不显示的问题

问题原因

你看不到淡出动画的核心原因是:在添加淡出动画后立刻将元素的display设为none。浏览器会直接隐藏该元素,完全跳过动画执行的过程,自然看不到淡出效果。

解决方案

需要等淡出动画完全执行完毕后,再隐藏当前元素并显示下一个元素。推荐使用animationend事件监听动画结束时机,这是最可靠的方式。

修改后的代码实现

首先保持你的CSS关键帧不变(可以优化下opacity的写法,用0和1代替百分比,效果一致):

@keyframes fade-in{
  0%{ opacity: 0; }
  100%{ opacity: 1; }
}

@keyframes fade-out{
  0%{ opacity: 1; }
  100%{ opacity: 0; }
}

然后重写changeDisplay函数:

function changeDisplay(section) {
  // 找到当前处于显示状态的section
  const currentSection = Array.from(section).find(el => window.getComputedStyle(el).display === 'grid');
  if (!currentSection) return;

  // 计算下一个要显示的section索引
  const currentIndex = Array.from(section).indexOf(currentSection);
  const nextIndex = currentIndex + 1 === section.length ? 0 : currentIndex + 1;
  const nextSection = section[nextIndex];

  // 给当前元素添加淡出动画,forwards让动画结束后保持最终状态
  currentSection.style.animation = 'fade-out 500ms forwards';

  // 监听动画结束事件,只执行一次
  currentSection.addEventListener('animationend', function handleEnd() {
    // 动画结束后隐藏当前元素
    currentSection.style.display = 'none';
    // 显示下一个元素并添加淡入动画
    nextSection.style.display = 'grid';
    nextSection.style.animation = 'fade-in 500ms forwards';
    // 移除事件监听,避免重复触发
    currentSection.removeEventListener('animationend', handleEnd);
  }, { once: true });
}

关键优化点

  • 用animationend替代即时修改display:确保动画完全执行后再切换元素状态,避免浏览器跳过动画。
  • 使用forwards关键字:让动画结束后保持最后一帧的样式(比如淡出后opacity保持0),视觉过渡更自然。
  • 避免重复事件绑定:通过{ once: true }配置让事件只执行一次,防止多次调用函数时出现异常。

替代方案(不推荐但简单)

如果不想使用事件监听,可以用setTimeout延迟修改display,延迟时间要和动画时长一致:

function changeDisplay(section) {
  const currentSection = Array.from(section).find(el => window.getComputedStyle(el).display === 'grid');
  if (!currentSection) return;

  const currentIndex = Array.from(section).indexOf(currentSection);
  const nextIndex = currentIndex + 1 === section.length ? 0 : currentIndex + 1;
  const nextSection = section[nextIndex];

  currentSection.style.animation = 'fade-out 500ms';
  // 延迟500ms(和动画时长一致)后切换状态
  setTimeout(() => {
    currentSection.style.display = 'none';
    nextSection.style.display = 'grid';
    nextSection.style.animation = 'fade-in 500ms';
  }, 500);
}

注意:这种方式依赖固定的延迟时间,若浏览器性能不足导致动画执行变慢,会出现元素提前隐藏的问题,不如animationend可靠。

内容的提问来源于stack exchange,提问作者eloreah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:25:50