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

如何计算Javascript平滑滚动结束时长以触发后续动画?

检测平滑滚动结束并触发动画的方案

不需要刻意计算平滑滚动的时长——因为Chrome等浏览器的平滑滚动速度会根据滚动距离、设备性能甚至用户设置动态调整,直接检测滚动停止的状态才是更可靠的方案。以下是两种实用的实现方式:

方法一:Scroll事件 + 定时器防抖

利用平滑滚动过程中浏览器会持续触发scroll事件的特性,通过定时器“防抖”:每次滚动时重置定时器,当定时器到期且没有新的滚动事件触发,就判定滚动已停止。

let scrollEndTimer;

// 监听全局滚动事件
window.addEventListener('scroll', () => {
  // 清除之前的定时器,重置计时
  clearTimeout(scrollEndTimer);
  // 设置100ms延迟(可根据实际测试调整,80-150ms都适配Chrome)
  scrollEndTimer = setTimeout(() => {
    // 滚动停止后执行你的动画
    runTargetAnimation();
  }, 100);
});

// 示例动画函数
function runTargetAnimation() {
  console.log('滚动已停止,开始执行动画');
  // 这里写你的动画逻辑,比如元素淡入、位移等
}

方法二:RequestAnimationFrame 跟踪滚动位置

通过requestAnimationFrame同步浏览器渲染帧,对比连续几帧的滚动位置,若位置不变则判定滚动停止,精度比定时器更高。

let lastScrollPos = window.scrollY;
let stationaryFrameCount = 0;
let animationFrameId;

function checkScrollStop() {
  const currentScrollPos = window.scrollY;
  
  if (currentScrollPos === lastScrollPos) {
    stationaryFrameCount++;
    // 连续3帧位置不变(约50ms,对应60fps),判定滚动停止
    if (stationaryFrameCount >= 3) {
      runTargetAnimation();
      // 停止检测
      cancelAnimationFrame(animationFrameId);
      return;
    }
  } else {
    stationaryFrameCount = 0;
    lastScrollPos = currentScrollPos;
  }
  
  animationFrameId = requestAnimationFrame(checkScrollStop);
}

// 触发平滑滚动后启动检测(比如点击锚点后调用)
// checkScrollStop();

function runTargetAnimation() {
  console.log('滚动已停止,开始执行动画');
  // 你的动画逻辑
}

关键说明

  • 无需纠结滚动速度计算:浏览器的平滑滚动算法是黑盒,不同场景下速度差异极大,直接检测停止状态比预估时长更稳定。
  • 延迟参数可调整:第一种方法的100ms延迟可根据测试微调,确保在Chrome各种滚动场景下都能准确触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:45:35