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 相关文章推荐
XmlUtils JS操作XML工具类
Oct 01 Javascript
使用js判断TextBox控件值改变然后出发事件
Mar 07 Javascript
javascript比较两个日期的先后示例代码
Dec 31 Javascript
JavaScript之数组(Array)详解
Apr 01 Javascript
jQuery基于扩展简单实现倒计时功能的方法
May 14 Javascript
老生常谈js动态添加事件--- 事件委托
Jul 19 Javascript
JavaScript编写一个简易购物车功能
Sep 17 Javascript
微信分享调用jssdk实例
Jun 08 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
May 16 Javascript
详解vue组件中使用路由方法
Feb 12 Javascript
微信小程序学习笔记之目录结构、基本配置图文详解
Mar 28 Javascript
微信小程序个人中心的列表控件实现代码
Apr 26 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
php知道与问问的采集插件代码
2010/10/12 PHP
win7+apache+php+mysql环境配置操作详解
2013/06/10 PHP
PHP进程通信基础之信号
2017/02/19 PHP
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
jquery 年会抽奖程序
2011/12/22 Javascript
关于jquery的多个选择器的使用示例
2013/10/18 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
2014/02/11 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
js实现的简洁网页滑动tab菜单效果代码
2015/08/24 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
2017/02/09 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
微信公众号菜单配置微信小程序实例详解
2017/03/31 Javascript
BootStrap 导航条实例代码
2017/05/18 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
2020/08/14 Javascript
js删除对象中的某一个字段的方法实现
2021/01/11 Javascript
[13:25]VP vs VICI (BO3)
2018/06/07 DOTA
使用python绘制人人网好友关系图示例
2014/04/01 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
Python3实现腾讯云OCR识别
2018/11/27 Python
详解Python 函数如何重载?
2019/04/23 Python
Django中create和save方法的不同
2019/08/13 Python
PyCharm 专业版安装图文教程
2020/02/20 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
matplotlib相关系统目录获取方式小结
2021/02/03 Python
俄罗斯连接商品和买家的在线平台:goods.ru
2020/11/30 全球购物
解释一下钝化(Swap out)
2016/12/26 面试题
营销主管自我评价怎么写
2013/09/19 职场文书
学校介绍信范文
2014/01/14 职场文书
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
八一建军节活动方案
2014/02/10 职场文书
模具专业自荐信
2014/05/29 职场文书
十二月早安励志心语大全
2019/12/03 职场文书
如何在CocosCreator里画个炫酷的雷达图
2021/04/16 Javascript
Python基础学习之奇异的GUI对话框
2021/05/27 Python
《Estab Life》4月6日播出 正式PV、主视觉图公开
2022/03/20 日漫