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

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

  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];
}
}

  就写到这里了~,睡个午觉QAQ

  

JS —— 轮播图中的缓动函数的封装的更多相关文章

  1. 纯js轮播图练习-2,js+css旋转木马层叠轮播

    基于css3的新属性,加上js的操作,让现在js轮播图花样越来越多. 而现在出现的旋转木马层叠轮播的轮播图样式,却是得到了很多人都喜爱和投入使用. 尤其是在各大软件中,频繁的出现在大家的眼里,在web ...

  2. JS轮播图(网易云轮播图)

    JS 轮播图 写在前面 最聪明的人是最不愿浪费时间的人.--但丁 实现功能 图片自动切换 鼠标移入停止自动播放,显示按钮 点击按钮,实现前后翻 鼠标移入小圆圈,可以跳转到对应图片 点击左右两侧图片部分 ...

  3. JavaScript的案例(数据校验,js轮播图,页面定时弹窗)

    1.数据校验            步骤            1.确定事件(onsubmit)并绑定一个函数            2.书写这个函数,获取数据,并绑定id            3. ...

  4. 纯js轮播图练习-1

    偶尔练习,看视频自己学着做个简单的纯JS轮播. 简单的纯js轮播图练习-1. 样子就是上面图片那样,先不管好不好看,主要是学会运用和理解轮播的原理 掌握核心的理论知识和技术的操作,其他的都可以在这个基 ...

  5. javascript原生js轮播图

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. js轮播图和bootstrap中的轮播图

    js中的轮播图案例: <!DOCTYPE html><html lang="en"> <head> <meta charset=" ...

  7. 手把手原生js轮播图

    在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用 ...

  8. 用require.js封装原生js轮播图

    index.html页面: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...

  9. 微信小程序之swiper轮播图中的图片自适应高度

    小程序中的轮播图很简单,官方都有例子的,但是唯一的缺陷就是swiper是固定死的150px高度,这样如果传入的图片大于这个高度就会被隐藏.辣么,怎样让图片自适应不同分辨率捏. 我的思路是:获取屏幕宽度 ...

随机推荐

  1. VS2015预览

    VS2015预览版体验   .NET开源了,JAVA颤抖吧...据说VS2015可以开发android,ios,wp应用程序了,还可以开发能运行在mac,linux上的ASP.NET网站,如果真是这样 ...

  2. Android摘要ImageView的scaleType属性

    Android在ImageView的scaleType有8一个选项 1 matrix不正确图像放大,原来自view在左上角绘制图片(片不变形): 2 fitXY将图片所有绘制到view中,可是图片会变 ...

  3. IE8下div中2个button仅仅显示一个

    IE8下div中2个button仅仅显示一个,代码例如以下: <div id="adviceType" style="display: none;" &g ...

  4. [译]Java垃圾回收是如何工作的

    说明:这篇文章来翻译来自于Javapapers 的How Java Garbage Collection Works 这部分教程是为了理解Java垃圾回收的基础以及它是如何工作的.这是垃圾回收系列教程 ...

  5. 一个逗比web前端的理想

    加入博客园也5年多了.平时博客也写的少,但是每天都会上来“偷窥”,你们的一举一动我都知道.呵呵~ 最近看了些小伙伴们写的一些文章自己也难免有些感触.最近也精神有些萎靡,也想写点什么记录下个人的成长经历 ...

  6. linux下监控进程需掌握的四个命令

    linux下监控进程需掌握的四个命令   在LInux系统下,最困难的工作之一就是跟踪正在系统中运行的程序,尤其是现在,图形桌面使用很多的程序,只是为了生成一个桌面环境,系统中运行了太多的进程,幸运的 ...

  7. Binder机制,从Java到C (10. Binder驱动)

    Binder驱动的代码都在kernel里面,这里就简单讲一下里面涉及到的几个东西: 1.MemoryBinder其实本质上就是一中数据传输方式,这种方式是通过binder driver实现的. 我们知 ...

  8. android通过程序收起通知栏

    1.  添加权限 <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> 2. ...

  9. 浅谈DevExpress<二>:设计一个完整界面(1)

    昨天谈了界面的换肤问题,今天拿一个简单的界面来介绍一下怎么设计一个五脏俱全的界面,总体效果如下图(种类的图片随便找的^^):

  10. sql 数据库的备份还原问题

    今天工作中犯了一个严重的错误,就是在sql中写了一个update语句,还没写条件呢,结果误按了F5,唉,太佩服自己啦...这个脑子怎么不管用了呢?? 唉不说了,我在网上翻来覆去的找资料,最终想是不是可 ...