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 相关文章推荐
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
Feb 03 Javascript
JS匀速运动演示示例代码
Nov 26 Javascript
jquery checkbox实现单选小例
Nov 27 Javascript
Javascript动画的实现原理浅析
Mar 02 Javascript
JS实现图片高斯模糊切换效果的焦点图实例
Jan 21 Javascript
jQuery实现一个简单的轮播图
Feb 19 Javascript
JavaScript实现256色转灰度图
Feb 22 Javascript
详解如何实现一个简单的 vuex
Feb 10 Javascript
Electron-vue开发的客户端支付收款工具的实现
May 24 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
Jul 17 Javascript
JS前端宏任务微任务及Event Loop使用详解
Jul 23 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过滤敏感词的示例
2014/03/31 PHP
php上传大文件失败的原因及应对策略
2015/10/20 PHP
详解php curl带有csrf-token验证模拟提交方法
2018/04/18 PHP
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
2010/05/06 Javascript
js 回车提交表单两种实现方法
2012/12/31 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
js实现继承的5种方式
2015/12/01 Javascript
Vue.js每天必学之方法与事件处理器
2016/09/06 Javascript
jQuery Ajax请求后台数据并在前台接收
2016/12/10 Javascript
js 实现省市区三级联动菜单效果
2017/02/20 Javascript
基于Vue实现timepicker
2017/04/25 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
jquery之基本选择器practice(实例讲解)
2017/09/30 jQuery
AngularJS监听ng-repeat渲染完成的两种方法
2018/01/16 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
Vue的props父传子的示例代码
2020/05/20 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
2020/07/20 Javascript
[01:32]DOTA2 2015国际邀请赛中国区预选赛第四日战报
2015/05/29 DOTA
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
python3 实现的人人影视网站自动签到
2016/06/19 Python
Python实现七彩蟒蛇绘制实例代码
2018/01/16 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
Python3.5基础之NumPy模块的使用图文与实例详解
2019/04/24 Python
Python画图高斯分布的示例
2019/07/10 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
html5使用canvas压缩图片的示例代码
2018/09/11 HTML / CSS
德国高尔夫商店:Golfshop.de
2019/06/22 全球购物
STP的判定过程
2012/10/01 面试题
两道JAVA笔试题
2016/09/14 面试题
技校毕业生的自我评价
2013/12/27 职场文书
残疾人创业典型事迹
2014/02/01 职场文书
机关党员三严三实心得体会
2014/10/13 职场文书
2014年村委会工作总结
2014/11/24 职场文书
接收函格式
2015/01/30 职场文书
python b站视频下载的五种版本
2021/05/27 Python