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

如何在.active类每次激活时重复触发CSS动画?

解决图片滑块切换时CSS动画仅播放一次的问题

嘿,我来帮你搞定这个问题!你遇到的核心痛点是:CSS动画默认只会在元素首次渲染、样式首次应用时执行一次。当你的滑块切换,.active类转移到新元素上时,旧元素的动画已经跑完了,新元素因为动画属性一开始就存在,浏览器不会重新触发它。不过我们可以通过结合你提到的.play类来实现动画的重复播放,下面给你两种可行的方案:

方案一:JavaScript配合.play类重置动画

这种方法最直接可控,通过监听滑块切换事件,动态添加/移除.play类来强制触发动画:

步骤1:调整CSS,让动画仅在.play类生效时执行

把动画属性从基础样式中剥离,放到.play类里,这样只有当元素拥有这个类时才会播放动画:

.article.active { 
  height: 75px; 
  margin-top: -109px; 
  margin-left: -70px; 
  color: white; 
  width: 100%; 
  opacity: 0.8; 
  z-index: 105; 
}
.article-num { 
  background: red; 
  float: right; 
  margin-top: 20px; 
  width: 0; 
  height: 32px; 
  padding: 0; 
  font-size: 27px; 
  opacity: 0; 
}
.article-num.play {
  animation-name: movingnum; 
  animation-duration: 4.7s; 
  animation-delay: 200ms; 
  animation-fill-mode: forwards; 
}
.article-paragraph { 
  top: 24px; 
  background: black; 
  width: 0; 
  height: 23px; 
  padding: 0; 
  float: right; 
  z-index: 30; 
  text-align: right; 
  opacity: 0; 
}
.article-paragraph.play {
  animation-name: movingpar; 
  animation-delay: 400ms; 
  animation-duration: 4.2s; 
  animation-fill-mode: forwards; 
}
/* keyframes 保持不变 */
@keyframes movingnum { 
  0%, 100% { width: 0px; } 
  10%, 90% { width: 31px; padding: 6.7px; opacity: 1; } 
}
@keyframes movingpar { 
  0%, 100% { width: 0px; opacity: 0; } 
  10%, 90% { width: 300px; padding: 11px; opacity: 1; } 
}

步骤2:添加滑块切换监听代码

从你的HTML能看出用的是Swiper滑块,我们可以监听它的slideChange事件,在切换时重置.play类:

// 初始化Swiper(如果还没初始化)
const swiper = new Swiper('.swiper-container', {
  // 这里填你的Swiper配置项
});

// 监听滑块切换事件
swiper.on('slideChange', function() {
  // 先移除所有元素的.play类
  document.querySelectorAll('.article-num.play, .article-paragraph.play').forEach(el => {
    el.classList.remove('play');
  });
  
  // 强制浏览器重绘(关键!否则直接加类可能不触发动画)
  void document.body.offsetWidth;
  
  // 给当前激活的.slide下的元素添加.play类
  const activeArticle = document.querySelector('.swiper-slide-active .article');
  if (activeArticle) {
    activeArticle.querySelector('.article-num').classList.add('play');
    activeArticle.querySelector('.article-paragraph').classList.add('play');
  }
});

方案二:纯CSS配合父元素.play类(仍需少量JS触发)

如果想尽量少用JS,可以通过父元素的.play类结合兄弟选择器触发动画,但还是需要JS来重置父元素的.play类:

修改后的CSS

/* 基础样式保持不变 */
.article.active { 
  height: 75px; 
  margin-top: -109px; 
  margin-left: -70px; 
  color: white; 
  width: 100%; 
  opacity: 0.8; 
  z-index: 105; 
}
.article-num { 
  background: red; 
  float: right; 
  margin-top: 20px; 
  width: 0; 
  height: 32px; 
  padding: 0; 
  font-size: 27px; 
  opacity: 0; 
}
.article-paragraph { 
  top: 24px; 
  background: black; 
  width: 0; 
  height: 23px; 
  padding: 0; 
  float: right; 
  z-index: 30; 
  text-align: right; 
  opacity: 0; 
}

/* 当父滑块拥有.play类时,触发子元素动画 */
.swiper-slide.play .article.active .article-num {
  animation-name: movingnum; 
  animation-duration: 4.7s; 
  animation-delay: 200ms; 
  animation-fill-mode: forwards; 
}
.swiper-slide.play .article.active .article-paragraph {
  animation-name: movingpar; 
  animation-delay: 400ms; 
  animation-duration: 4.2s; 
  animation-fill-mode: forwards; 
}

/* keyframes 保持不变 */
@keyframes movingnum { 
  0%, 100% { width: 0px; } 
  10%, 90% { width: 31px; padding: 6.7px; opacity: 1; } 
}
@keyframes movingpar { 
  0%, 100% { width: 0px; opacity: 0; } 
  10%, 90% { width: 300px; padding: 11px; opacity: 1; } 
}

对应的JS触发代码

同样监听Swiper切换事件,重置父元素的.play类:

const swiper = new Swiper('.swiper-container', {
  // 你的Swiper配置
});

swiper.on('slideChange', function() {
  // 移除所有滑块的.play类
  document.querySelectorAll('.swiper-slide.play').forEach(el => {
    el.classList.remove('play');
  });
  
  // 强制浏览器重绘
  void document.body.offsetWidth;
  
  // 给当前激活的滑块添加.play类
  document.querySelector('.swiper-slide-active').classList.add('play');
});

为什么需要强制重绘?

浏览器会优化样式变化,如果直接移除再添加类,可能会被合并成一次样式更新,动画就不会重新触发。void document.body.offsetWidth会强制浏览器计算元素尺寸,触发重绘,这样后续的类添加就会被识别为新的样式变化,从而重新执行动画。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:56:26