使某个dom元素匀速滑动到容器顶部

需求

  • 我有个侧面的菜单 , 点击对应的菜单标题, 可以让左侧的容易里对应标题滑到最顶上
  • 于是我封装了一个缓动函数

这个函数接受3个参数

  • 需要滚动的最外层的容器
  • 滚动到什么距离
  • 滚动时间

注意点

第一个参数的最外层的容器 , 需要滚动条( 没滚动条是没有办法滚动的 )
第二个参数是滚动的距离 , 其实也就是内部需要置顶的子元素的offsetTop ( 子元素距离顶部的距离 )
第三个参数可以不传,有默认值

smoothScrollToTop(element, targetScrollTop, duration = 500) {
      const startingScrollTop = element.scrollTop;
      console.log(startingScrollTop, "startingScrollTop11111");
      const startTime = performance.now();
      const scrollDistance = targetScrollTop - startingScrollTop;

      function animateScroll(currentTime) {
        const elapsedTime = currentTime - startTime;
        const progress = Math.min(elapsedTime / duration, 1);
        const easeInOutQuad = (t) =>
          t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

        element.scrollTop =
          startingScrollTop + scrollDistance * easeInOutQuad(progress);

        if (progress < 1) {
          requestAnimationFrame(animateScroll);
        }
      }

      requestAnimationFrame(animateScroll);
    },

使用demo

  • 直接复制保存html预览
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="btn">我要让元素滑动置顶</button>
  <div id="box">
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1 id="top">需要置顶的元素</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
    <h1>1</h1>
  </div>
</body>
<script>

  function smoothScrollToTop(element, targetScrollTop, duration = 500) {
    const startingScrollTop = element.scrollTop;
    const startTime = performance.now();
    const scrollDistance = targetScrollTop - startingScrollTop;

    function animateScroll(currentTime) {
      const elapsedTime = currentTime - startTime;
      const progress = Math.min(elapsedTime / duration, 1);
      const easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

      element.scrollTop = startingScrollTop + (scrollDistance * easeInOutQuad(progress));

      if (progress < 1) {
        requestAnimationFrame(animateScroll);
      }
    }
    requestAnimationFrame(animateScroll);
  }

  const btn = document.querySelector(`#btn`)
  btn.addEventListener(`click`, () => {
    const element = document.querySelector(`#top`)
    const offsetTop = element.offsetTop;
    smoothScrollToTop(box, offsetTop);
  })
</script>

</html>

<style>
  #btn {
    position: fixed;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
  }

  #box {
    height: 500px;
    background-color: red;
    overflow: scroll;
    margin-left: 100px;
  }
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值