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 相关文章推荐
爱恋千雪-US-AscII加密解密工具(网页加密)下载
Jun 06 Javascript
js常用排序实现代码
Dec 28 Javascript
原生JavaScript编写俄罗斯方块
Mar 30 Javascript
解决js图片加载时出现404的问题
Nov 30 Javascript
关于原生js中bind函数的简单实现
Aug 10 Javascript
10分钟掌握XML、JSON及其解析
Dec 06 Javascript
从源码看angular/material2 中 dialog模块的实现方法
Oct 18 Javascript
jquery实现楼层滚动效果
Jan 01 jQuery
关于vuejs中v-if和v-show的区别及v-show不起作用问题
Mar 26 Javascript
基于Vue的侧边目录组件的实现
Feb 05 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
May 14 Javascript
详解VUE中的插值( Interpolation)语法
Oct 18 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
ADODB类使用
2006/11/25 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
2014/12/18 PHP
解读PHP中的垃圾回收机制
2015/08/10 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
javascript下4个跨浏览器必备的函数
2010/03/07 Javascript
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
基于jquery的$.ajax async使用
2011/10/19 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
JS不间断向上滚动效果代码
2013/12/25 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
js面向对象之静态方法和静态属性实例分析
2015/01/10 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
JS 清除字符串数组中,重复元素的实现方法
2016/05/24 Javascript
jQuery Validate插件实现表单验证
2016/08/19 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
2016/09/09 Javascript
JS自定义函数实现时间戳转换成date的方法示例
2017/08/27 Javascript
node.js 模块和其下载资源的镜像设置的方法
2018/09/06 Javascript
layer弹出子iframe层父子页面传值的实现方法
2018/11/22 Javascript
JS实现水平移动与垂直移动动画
2019/12/19 Javascript
如何使用七牛Python SDK写一个同步脚本及使用教程
2015/08/23 Python
Python+微信接口实现运维报警
2016/08/27 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
Python 实现RSA加解密文本文件
2020/12/30 Python
美国婚礼礼品网站:MyWeddingFavors
2018/09/26 全球购物
双立人美国官方商店:ZWILLING集团餐具和炊具
2020/05/07 全球购物
翻译专业应届生求职信
2013/11/23 职场文书
工程专业求职自荐书范文
2014/02/18 职场文书
毕业生个人求职自荐信
2014/02/26 职场文书
升学宴主持词
2014/04/02 职场文书
解除劳动合同协议书
2014/04/14 职场文书
三方合作协议书范本
2014/04/18 职场文书
建筑工地大门标语
2014/06/18 职场文书
优秀校长事迹材料
2014/12/24 职场文书
文明上网主题班会
2015/08/14 职场文书