目录
今天使用js封装一个简单的动画函数,并且传入一个回调函数以供实现其他的功能。
网页常见的滑动效果。使用css中的过渡和动画也可以实现,这里主要复习巩固JS的知识。
接下来说一下动画实现的原理,就是通过定时器setinterval()不断移动盒子位置。
1、添加函数
首先,要实现移动的动画我们需要给函数传入两个参数,那就是要运动的对象和运动多少距离。
function animate(obj,target){}//传入对象和移动的距离
2、添加定时器
下面添加一个定时器,给定时器一个名字方便我们后面需要停止定时器,为了区分定时器的名字,这里用对象属性名的方式命名。
function animate(obj,target){
obj.timer=setInterval(function(){},30) //给不同元素记录不同定时器
}
3、计算和判断
接下来是计算,使用offset获取元素当前位置,然后每次加1px,这样就可以实现基本的效果了。
注意这里一定要给元素开启定位,因为我们修改的是left.
function animate(obj,target){
obj.timer=setInterval(function(){
obj.style.left=obj.offsetLeft+1+'px';
},30)
}
这样我们还需要让他到达对应的位置停下来才可以,那就加个判断条件。达成条件清除定时器。
function animate(obj,target){
obj.timer=setInterval(function(){
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}else{
obj.style.left=obj.offsetLeft+1+'px';
}
},30)
}
下面写一个div看看效果
4、实现缓动画
这里也是实现了,但是有些页面是一个缓慢停止的元素,因此我们可以做一个缓慢的动画。
下面说一下缓动画的原理:就是让移动距离慢慢变小
核心算法:(目标值-现在的位置)/10 作为每次移动的距离步长
下面我们就重新改一下代码,参考上面这个算法,但是里面会有小数,我们这里采取取整的方法,四舍五入的话会导致我们丢掉很多距离,所以我们这里采用Math.ceil向上取整,但是负数的话这个函数会向下取整,所以负数我们单独使用floor向上取整。也就是再加个判断条件。这里采用三元表达式,代码如下
function animate(obj,target){
obj.timer=setInterval(function(){
//避免小数问题这里我们取整
var step=(target-obj.offsetLeft)/10;
step=step>0? Math.ceil(step):Math.floor(step); //大于0 向上取整 小于0向下取整
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}else{
//把每次加1 改为一个不断变小的值可以实现缓动画
obj.style.left=obj.offsetLeft+step+'px';
}
},30)
再看一下效果
5、解决定时器重复添加问题
这样我们就完成了一个简单动画函数的封装,但是一般我们触发这个动画都会有一个条件,比如鼠标移入滑动出来,点击按钮移动,但是如果我们不断触发这个条件(比如一直点按钮触发动画),就会不断添加定时器,导致我们的动画越来越快。因此我们要在每次执行前添加一个清除定时器。代码如下
function animate(obj,target){
//每次执行前清除上一个定时器 避免重复导致动画越来越快
clearInterval(obj.timer);
obj.timer=setInterval(function(){
//避免小数问题这里我们取整
var step=(target-obj.offsetLeft)/10;
step=step>0? Math.ceil(step):Math.floor(step);
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}else{
obj.style.left=obj.offsetLeft+step+'px';
}
},30)
}
6、添加回调函数
回调函数:将函数作为一个参数传到另一个函数里面,那个函数执行完再执行这个函数。
我们在动画结束也就是定时器结束的时候往往还想添加一些其他的效果,比如停止移动到终点后变个颜色。这时候我们就可以添加一个回调函数来实现这个功能。
也就是给我们的函数多加一个参数,这个参数传入函数就可以了
function animate(obj,target,callback){}
但是我们要是不想用这个函数怎么办呢,那就加个判断有没有这个函数
代码如下:
function animate(obj,target,callback){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
var step=(target-obj.offsetLeft)/10;
step=step>0? Math.ceil(step):Math.floor(step);
if(obj.offsetLeft==target){
clearInterval(obj.timer);
if(callback){ //加在我们定时器结束后,判断有没有这个函数,有就执行
callback();
}
}else{
obj.style.left=obj.offsetLeft+step+'px';
}
},30)
}
这样比如我们想移动后变个颜色就可以这样写
var div=document.querySelector('div');
animate(div,200,function(){
div.style.backgroundColor='red';
}
)
这样我们的动画函数就封装结束了,也可以自己改变距离和时间。