实现回到顶部动画效果

1,805 阅读1分钟

方式一

这种方式是每次移动固定的高度。这种方式下,回到顶部的时间和页面已滚动的高度成正比。

  function handleClick() {
    // 兼容
    const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16));
    const frameFunc = () => {
      if (document.documentElement.scrollTop > 0) {
        document.documentElement.scrollTop -= 40;
        rAF(frameFunc)
      }
    }
    rAF(frameFunc)
  }

方式二

这种方式是回到顶部使用固定的时间,示例是500ms。根据页面时间计算页面需要滚动的位置。

  function handleClick() {
    // 记录开始时间
    const beginTime = Date.now()
    // 初始位置
    const beginValue = document.documentElement.scrollTop;
    const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16))
    const frameFunc = () => {
      // 进度,500ms 内将页面滚动到顶部
      const progress = (Date.now() - beginTime) / 500
      if (progress < 1) {
        // 根据进度修改 scrollTop 的值
        document.documentElement.scrollTop = beginValue * (1 - progress)
        rAF(frameFunc)
      } else {
        document.documentElement.scrollTop = 0
      }
    }
    rAF(frameFunc)
  }

方式二(优化版)

上面页面滚动速度都是线性的,我们还可以添加一些缓动效果。 我们试一下 easeInOutCubic 的效果,计算公式可以参考缓动曲线相关公式

先定义缓动曲线的计算方式

  const cubic = (value) => Math.pow(value, 3)

  const easeInOutCubic = (value) => value < 0.5 ?
    cubic(value * 2) / 2 :
    1 - cubic((1 - value) * 2) / 2

再将下面这行代码进行修改

// document.documentElement.scrollTop = beginValue * (1 - progress)
document.documentElement.scrollTop = beginValue * (1 - easeInOutCubic(progress))

参考