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

如何在JavaScript的wheel事件中限制GSAP动画仅触发一次?

解决滚动触发GSAP动画多次的问题

方案1:完善状态锁+冷却时间

你的现有代码用了isAnimating状态锁,但触摸板长滚动时wheel事件会连续高频触发,可能在状态锁更新前就多次进入判断。可以给状态锁加上冷却时间,确保动画结束后或一段时间内不再响应滚动触发:

let isAnimating = false;
const COOLDOWN_TIME = 1000; // 冷却时间,可根据动画实际时长调整

window.addEventListener('wheel', (event) => {
  if (!isAnimating) {
    isAnimating = true;
    // 播放GSAP动画
    slideTimelines[0].play(0).then(() => {
      // 动画结束后延迟解锁,避免短时间内重复触发
      setTimeout(() => {
        isAnimating = false;
      }, COOLDOWN_TIME);
    });
  }
});

方案2:使用防抖函数

防抖函数可以让连续触发的高频事件只执行一次,完美适配这类滚动触发场景:

let isAnimating = false;

// 防抖函数:连续触发时只执行最后一次
function debounce(func, delay = 500) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, args), delay);
  };
}

const handleWheel = debounce(() => {
  if (!isAnimating) {
    isAnimating = true;
    slideTimelines[0].play(0).then(() => {
      isAnimating = false;
    });
  }
});

window.addEventListener('wheel', handleWheel);

方案3:结合滚动方向判断(可选)

如果只需要在特定滚动方向(比如向下)触发动画,可以加上方向判断,进一步减少误触发:

let isAnimating = false;
const COOLDOWN_TIME = 1000;

window.addEventListener('wheel', (event) => {
  // 仅响应向下滚动(deltaY>0),可根据需求改为向上(deltaY<0)
  if (!isAnimating && event.deltaY > 0) {
    isAnimating = true;
    slideTimelines[0].play(0).then(() => {
      setTimeout(() => {
        isAnimating = false;
      }, COOLDOWN_TIME);
    });
  }
});

关键说明

  • isAnimating状态锁必须绑定到GSAP动画的完成回调(.then()),确保动画完全结束后才解锁。
  • 冷却时间或防抖延迟建议设置为略短于动画时长,既保证只触发一次,又不会让用户等待太久。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:54:24