JS轮播图中缓动函数的封装


Posted in Javascript onNovember 25, 2020

轮播图的根本其实就是缓动函数的封装,如果说轮播图是一辆跑动的汽车,那么缓动函数就是它的发动机,今天本文章就带大家由简入繁,封装属于自己的缓动函数~~

我们从需求的角度开始,首先给出一个简单需求:

1、我想让页面中的一个盒子从开始的位置匀速向右运动到200px的地方,该怎么实现?

分析:

1)我们需要知道盒子在哪个地方,这个可以通过offsetLeft属性去获取;

 2)要让盒子匀速运动,对于js肯定需要setInterval了;

3)要让盒子向右边跑起来?那就是需要不停改变盒子与左边起始点的距离,有margin-left,还有定位的left,这里我选择了改变绝对定位的left;

 4)跑到离开始点200px的距离我们要停下来,使用clearInterval就可以了。 

接下来直接上代码了

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="UTF-8" />
 <title>Document</title>
 <style type="text/css">
  * {
  margin: 0;
  padding: 0;
  }
  div {
  position: absolute;
  top: 50px;
  width: 100px;
  height: 100px;
  background-color: red;
  }
  input {
  width: 100px;
  height: 30px;
  color: #fff;
  background-color: yellowgreen;
  }

 </style>
 </head>

 <body>
 <div></div>
 <input type="button" value="移动到200" />


 <script type="text/javascript">
  // 获取到元素(这里有个小细节,如果给元素设置了id名,即便不使用获取元素的方法,也能通过这个id名获取到元素哦~~大家可以自己尝试一下)
  var btn = document.querySelector('input'),
   dv = document.querySelector('div');
  // 添加点击事件
  btn.addEventListener('click',function() {
  var timer = null,// 保存定时器
   currentDistance = dv.offsetLeft, // 当前离父盒子的距离
   step = 8,// 每次改变的距离
   target = 200;// 目标距离
  timer = setInterval(function() {
   currentDistance += step;// 当前距离 = 上一个当前距离 + 改变的距离
   if((target - currentDistance) < step) { 
   currentDistance = target; // 如果目标距离与当前距离的差小于了要改变的距离,这时候我们就直接让当前距离等于目标距离,防止盒子停下来的时候有误差
   clearInterval(timer); // 清楚定时器
   timer = null; // 将timer解绑,释放内存
   }
   dv.style.left = currentDistance + 'px'; // 最核心的一步,改变盒子的left为当前距离
  },17)
  })
 </script>
 </body>
</html>

 2、一个初步运动的效果实现了,那么接下来我们改进了需求:

盒子运动到200px的位置后,我们要让盒子继续运动到400px的位置?

分析:

1)、这时候要有两个按钮点击,一个运动到200px,一个运动到400px

 2)、虽然有两个运动,但是其使用的功能都是一样,都是从一个点移动到另一个点,所以我们考虑将1中的运动封装一个函数,以供复用。

上代码~

 

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8" />
 <title>Document</title>
 <style type="text/css">
 * {
 margin: 0;
 padding: 0;
 }
 div {
 position: absolute;
 top: 50px;
 width: 100px;
 height: 100px;
 background-color: red;
 }
 input {
 width: 100px;
 height: 30px;
 color: #fff;
 background-color: yellowgreen;
 }

 </style>
</head>

<body>
 <div></div>
 <input type="button" value="移动到200" />
 <input type="button" value="移动到400" />
 <script type="text/javascript">
 // 封装函数,盒子和目标距离都是不确定的,我们可以将他们作为参数传递。
 function animation(tag,target) {
 var timer = null,
  currentDistance = tag.offsetLeft,
  step = 5;
 step = currentDistance < target? step: -step;// 判断step的正负,200到400时是递增,400到200时是递减
 timer = setInterval(function() {
 if(Math.abs(currentDistance - target) > Math.abs(step)) { // 这里判断条件也要略作改动,使用绝对值进行比较
  currentDistance += step; /
  tag.style.left = currentDistance + 'px';
 }else {
  tag.style.left = target + 'px' // 当当前距离与目标距离之间的差值小于step改变的距离时,我们直接让盒子移动到目标距离。
  clearInterval(timer);
  timer = null;
 }
 },17)
 }
 var btns = document.querySelectorAll('input'),
 dv = document.querySelector('div');
 btns[0].addEventListener('click',function() {
 animation(dv,200);
 })
 btns[1].addEventListener('click',function() {
 animation(dv,400);
 })
 </script>
</body>
</html>

3、盒子来回运动的函数我们封装好了,但是我们再想一下轮播图的滚动效果,它并不是匀速移动,而是最开始很块,在接近滚动完成时,速度又逐渐减低。

需求: 让盒子缓动(也就是变速运动) 

上代码~

function animation(tag,target) {
 var timer = null;
 timer = setInterval(function() {
 var currentDistance = tag.offsetLeft,
  step = (target - currentDistance) / 5;// 通过目标距离与当前距离的差除以5便达到了我们需要的变速运动,因为step每次定制器执行都要改变,所以放入定时器内
 step = step > 0 ? Math.ceil(step):Math.floor(step);// 这里如果将currentDistance定时器外面声明可以不用写,如果放在定时器内声明,因为offsetLeft取整的特性,要对step进行取整
 if(Math.abs(currentDistance - target) > Math.abs(step)) {
  currentDistance += step;
  tag.style.left = currentDistance + 'px';
 }else {
  tag.style.left = target + 'px'
  clearInterval(timer);
  timer = null;
 }
 },17)

好了,一个轮播图需要的最基本的缓动函数完成了~ 

这里补充一个比较完整的缓动函数:它的功能更全面一点,可以同时更改多样式。

function perfectAnimate(tag, obj, fn) {// 传三个参数,运动的盒子,对象(可以传多个属性),回调函数(在执行完后可以再执行自定义的功能)
 clearInterval(tag.timer);// 这里将定时器作为tag标签的属性保存,可以多次调用函数清除上一个定时器。
 tag.timer = setInterval(function () {
 var flag = true;
 for (var k in obj) {


 // 因为并不是所有属性都带px单位,所以这里进行判断分别设置 
  if (k == 'opacity') {
  var currentDistance = getStyle(tag, k) * 100,
   target = obj[k] * 100,
   step = (target - currentDistance) / 10;
  step = step > 0 ? Math.ceil(step) : Math.floor(step);
  currentDistance += step;
  tag.style[k] = currentDistance / 100;
  } else if (k == 'zIndex') {
  tag.style[k] = obj[k];
  else {
  var currentDistance = parseInt(getStyle(tag, k)) || 0,
   target = obj[k],
   step = (target - currentDistance) / 10;
  step = step > 0 ? Math.ceil(step) : Math.floor(step);
  currentDistance += step;
  tag.style[k] = currentDistance + 'px';
  }
  if (target != currentDistance) {
  flag = false // 只要还有属性没有运动完成,就不会清楚定时器
  }
 }
 if (flag) {
  clearInterval(tag.timer)
  fn && fn();// 所有定时器走完,这里执行回调函数,短路操作避免不传回调函数也不会报错。
 }
 }, 17)
}
// 获取样式的兼容函数,上面的缓动函数的依赖
function getStyle(tag, attr) {
 if (tag.currentStyle) {
 return tag.currentStyle[attr];
 } else {
 return getComputedStyle(tag, null)[attr];
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
非常好的js代码
Jun 27 Javascript
window.addEventListener来解决让一个js事件执行多个函数
Dec 26 Javascript
EasyUI中combobox默认值注意事项
Mar 01 Javascript
Bootstrap实现默认导航栏效果
Sep 21 Javascript
jQuery代码实现实时获取时间
Jan 29 Javascript
javascript 中的try catch应用总结
Apr 01 Javascript
JS实现分页浏览横向图片(类轮播)实例代码
Nov 06 Javascript
详解webpack+express多页站点开发
Dec 22 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
微信小程序用户授权,以及判断登录是否过期的方法
May 10 Javascript
微信小程序接入腾讯云验证码的方法步骤
Jan 07 Javascript
js 数组当前行添加数据方法详解
Jul 28 Javascript
JavaScript字符串对象
Jan 14 #Javascript
jquery mobile移动端幻灯片滑动切换效果
Apr 15 #Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
Jan 14 #Javascript
jQuery实现select模糊查询(反射机制)
Jan 14 #Javascript
Angular2-primeNG文件上传模块FileUpload使用详解
Jan 14 #Javascript
Angular2 PrimeNG分页模块学习
Jan 14 #Javascript
bootstrap datetimepicker日期插件使用方法
Jan 13 #Javascript
You might like
图象函数中的中文显示
2006/10/09 PHP
PHP实现变色验证码实例
2014/01/06 PHP
PHP采集类Snoopy抓取图片实例
2014/06/19 PHP
Laravel中Trait的用法实例详解
2016/03/16 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
PHP面向对象程序设计方法实例详解
2016/12/24 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
使用js写的一个简易的投票
2013/11/27 Javascript
JavaScript图片轮播代码分享
2015/07/31 Javascript
jquery获取css的color值返回RGB的方法
2015/12/18 Javascript
第七篇Bootstrap表单布局实例代码详解(三种表单布局)
2016/06/21 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
H5基于iScroll实现下拉刷新和上拉加载更多
2017/07/18 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
vue.js计算属性computed用法实例分析
2018/07/06 Javascript
JS如何在数组指定位置插入元素
2020/03/10 Javascript
javascript设计模式 ? 抽象工厂模式原理与应用实例分析
2020/04/09 Javascript
[01:13:18]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
2020/03/13 Python
基于Keras中Conv1D和Conv2D的区别说明
2020/06/19 Python
PyQt实现计数器的方法示例
2021/01/18 Python
HTML5时代CSS设置漂亮字体取代图片
2014/09/04 HTML / CSS
Turnbull & Asser官网:英国皇室御用的顶级定制衬衫
2019/01/31 全球购物
期末自我鉴定
2014/02/02 职场文书
让世界充满爱演讲稿
2014/05/24 职场文书
条幅标语大全
2014/06/20 职场文书
学生打架检讨书
2014/10/20 职场文书
2014年办公室人员工作总结
2014/12/09 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
2015新学期校长寄语(3篇)
2015/03/25 职场文书
2015年党支部书记工作总结
2015/05/21 职场文书
边城读书笔记
2015/06/29 职场文书
python实现大文本文件分割成多个小文件
2021/04/20 Python
Python装饰器的练习题
2021/11/23 Python
css之clearfix的用法深入理解(必看篇)
2023/05/21 HTML / CSS