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

JS设置的CSS transform与CSS动画冲突问题求助

问题解答

这确实是预期行为!当你使用animation-fill-mode: forwards时,动画结束后会将最终帧的属性值保留在元素的动画计算样式层中,而通过JS直接设置的transform属于元素的内联样式,优先级低于CSS动画的属性值——哪怕动画已经停止,浏览器依然会优先采用动画里定义的transform,这就是为什么你在调试工具里能看到两个transform但JS的设置不生效的原因。

下面给你几个简便的解决方法,不用移除forwards填充模式:

方法1:嵌套元素分离动画与视差逻辑

把需要执行淡入动画的内容放在内层div,外层div专门用来通过JS控制视差的transform。这样两个transform分别作用在不同元素上,完全不会冲突:

<!-- 外层容器:JS控制视差transform -->
<div class="parallax-wrapper">
  <!-- 内层元素:应用fade-in-b动画 -->
  <div class="animated-item">
    <!-- 你的内容 -->
  </div>
</div>

你的原有动画CSS可以完全保留,JS只需要修改.parallax-wrapper的transform即可:

// 示例:滚动时修改外层容器的translateY
window.addEventListener('scroll', () => {
  const scrollY = window.scrollY;
  document.querySelector('.parallax-wrapper').style.transform = `translateY(${scrollY * 0.5}px)`;
});

方法2:用CSS变量动态控制动画的transform值

修改你的动画定义,把translateY的数值换成CSS变量,这样JS可以通过修改变量值来间接调整transform,同时保留forwards的效果:

首先更新动画的CSS:

@keyframes fade-in-b {
  0% {
    opacity: 0;
    -webkit-transform: translateY(var(--anim-start-y, 40px));
    transform: translateY(var(--anim-start-y, 40px));
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(var(--anim-end-y, 0));
    transform: translateY(var(--anim-end-y, 0));
  }
}

然后在JS中,通过修改--anim-end-y变量来实现视差效果:

window.addEventListener('scroll', () => {
  const scrollY = window.scrollY;
  const parallaxOffset = scrollY * 0.5; // 视差系数,按需调整
  document.querySelector('.animated-item').style.setProperty('--anim-end-y', `${parallaxOffset}px`);
});

这种方法不需要修改DOM结构,动画的forwards依然会生效——因为最终帧的transform是基于CSS变量计算的,变量值变化时浏览器会自动重计算样式,从而实现动态的视差效果。


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

火山引擎 最新活动