实现对一个元素的滚动条进行平滑滚动至顶部的动画效果

news/2024/7/2 23:27:03

1.elementUI中的平滑滚动至顶部的动画效果代码

const cubic = value => Math.pow(value, 3);
const easeInOutCubic = value => value < 0.5
? cubic(value * 2) / 2
: 1 - cubic((1 - value) * 2) / 2;

const el = this.el;
const beginTime = Date.now();
const beginValue = el.scrollTop;
const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16));
const frameFunc = () => {
const progress = (Date.now() - beginTime) / 500;
if (progress < 1) {
el.scrollTop = beginValue * (1 - easeInOutCubic(progress));
rAF(frameFunc);
} else {
el.scrollTop = 0;
}
};
rAF(frameFunc);

/**

下面是代码的逐行解释:

定义一个函数 cubic,接收一个参数 value,返回 value 的三次方。
定义一个函数 easeInOutCubic,接收一个参数 value,并根据 value 的值计算出在动画过程中的缓动效果,使其在开始和结束时速度较慢,在中间过程速度较快。
定义一个变量 el,表示当前操作的元素对象。
定义一个变量 beginTime,记录动画开始的时间。
获取 el 元素的当前滚动高度(距离顶部的距离),并将其赋值给变量 beginValue。
定义一个变量 rAF,使用浏览器的 requestAnimationFrame 方法(如果不支持,则使用 setTimeout 方法代替)。
定义一个函数 frameFunc,用于在每一帧中执行滚动的计算和更新。
计算动画的进度值 progress,表示从动画开始到现在所经过的时间占总动画时间(这里是500毫秒)的百分比。
判断 progress 是否小于 1,若小于 1,则说明动画尚未完成,继续执行以下操作:
利用 easeInOutCubic 函数计算当前帧的滚动条距离顶部的位置,并更新 el 元素的滚动高度。
使用 rAF 函数请求下一帧继续执行 frameFunc。
若 progress 不小于 1,则说明动画已经完成,将 el 元素的滚动条滚动至顶部。
调用 rAF 函数,传入 frameFunc,开始执行动画。
总结:这段代码使用了 requestAnimationFrame 和 easeInOutCubic 缓动函数来实现一个元素滚动条的平滑滚动至顶部的动画效果。


*/

2.将上面的代码简化

const el = this.el;
const duration = 500;
const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16));

const scrollToTop = (startTime, startValue) => {
  const currentTime = Date.now();
  const progress = Math.min(1, (currentTime - startTime) / duration);

  el.scrollTop = startValue * (1 - progress);
  
  if (progress < 1) {
    rAF(() => scrollToTop(startTime, startValue));
  }
};

const beginTime = Date.now();
const beginValue = el.scrollTop;
rAF(() => scrollToTop(beginTime, beginValue));

/**
1.移除了 cubic 和 easeInOutCubic 函数,直接使用线性插值计算进度,代码更简洁。
2.将 frameFunc 函数改为 scrollToTop 函数,并将其作为递归调用,使代码逻辑更清晰。
    代码的基本逻辑和原来相似,使用 requestAnimationFrame 在每一帧中更新滚动条位置。这里的滚动动画效果将是线性的,即在动画过程中速度恒定。

*/

3.继续简化代码

使用Element.scrollTo方法并使用scroll-behavior: smooth的简化代码示例:

  1. 首先,在你的CSS样式表中加入以下代码:
    html {
      scroll-behavior: smooth;
    }

    这会将平滑滚动的效果应用到整个页面。

  2. 然后,使用scrollTo方法在JavaScript中触发滚动到顶部的操作:
    window.scrollTo({ top: 0, behavior: 'smooth' });

    这段代码相较于之前的实现更加简洁,因为我们使用了现代浏览器支持的scroll-behavior属性和scrollTo方法。这种方法的优势在于代码简洁,并且使用了原生的浏览器功能,因此性能更好。但请注意,这种方法在某些较旧的浏览器中可能不受支持。如果需要支持更多浏览器,请考虑使用上述更长的代码示例。


http://lihuaxi.xjx100.cn/news/1293890.html

相关文章

雅迪渐进、小牛徐行,两轮电动车“尖子生”竞争加剧

配图来自Canva可画 2023年中旬&#xff0c;两轮电动车品牌陆续上新车&#xff0c;对外展示品牌实力和创新力。 5月9日&#xff0c;哈啰智能电动车发布“极智系列”三款搭载了哈啰图灵T30智能平台的新车&#xff1b;5月10日&#xff0c;九号公司发布全新设计的E系列电摩顶配车型…

最佳实践|亚马逊可持续发展的架构模型

在过去的十年里面&#xff0c;亚马逊云科技一直都致力于帮助企业和开发者实现数字化转型&#xff0c;包括如何使用云技术帮助企业提高运营中资源利用率&#xff1b;如何通过云基础架构、容器、DevOps 进行业务的创新和敏捷性&#xff1b;未来的十年&#xff0c;亚马逊云科技将帮…

数据倾斜排查

一、问题现象 租户反馈&#xff0c;任务执行时长加长&#xff0c;执行过程中任务卡在 99%&#xff0c;大概率是出现了数据倾斜 二、排查过程 数据倾斜大多数都是大 key 问题导致的。排查方法如下&#xff1a; 1.时间判断 reduce 的时间比其他 reduce 时间长的多&#xff0c;大…

从四个角度全面认识 ChatGPT

传统语言模型是什么样的&#xff1f;ChatGPT 涌现出了哪些新能力&#xff1f;这些能力都是怎么做到的&#xff1f;在 ChatGPT 大模型时代&#xff0c;我们应该怎么做&#xff1f; 当下最引人注目的语言模型 ChatGPT 如火如荼&#xff0c;主要还是因为其能力远远超越了传统模型。…

劫持react组件

劫持props 假设我们有一个原组件&#xff0c;它接收一个 name prop&#xff0c;并显示一个问候语&#xff1a; // 原组件 function Greeting(props) {return <h1> Hello, {props.name}! </h1>; }我们可以定义一个高阶组件&#xff0c;它可以通过 props 传递一个 …

Linux教程——Linux用户和用户组(包含两者之间的关系)

Linux 是多用户多任务操作系统&#xff0c;换句话说&#xff0c;Linux 系统支持多个用户在同一时间内登陆&#xff0c;不同用户可以执行不同的任务&#xff0c;并且互不影响。 例如&#xff0c;某台 Linux 服务器上有 4 个用户&#xff0c;分别是 root、www、ftp 和 mysql&…

PDF如何转换成Word?PDF转Word方法分享!​

PDF大家都不陌生了吧&#xff1f;作为打工人&#xff0c;学生党的大家都知道&#xff0c;PDF是现在不可或缺的文件传输工具之一&#xff0c;不仅可将文档转为Word&#xff0c;还可以转成excel,ppt等各种形式&#xff0c;其重要性不言而喻&#xff0c;那么今天小编就跟大家具体说…

【Java】直接return 会触发try-catch 里面的finally的方法么

&#x1f431;‍&#x1f680;/背景 try-catch 主要的作用是捕获异常&#xff0c;那么程序没有异常&#xff0c;finally里面代码能否执行&#xff1f; 特别是如果我们前面进行了加锁等操作&#xff0c;没有释放锁&#xff0c;那不是会造成业务逻辑问题, 先说结论&#xff1a;…