运动函数
1、含义: 封装一个函数让一个元素改变现有状态,将来想要让元素运动的时候直接调用这个函数就可以了;
2、原理:利用定时器setInterval()不断移动盒子位置
3、实现步骤
=>获取当前盒子的位置
=>让盒子在当前位置上加上一个需要移动距离
=>利用定时器不断重复这个操作
=>加一个定时器结束的条件
注意:此元素需要添加定位,才可以使用 元素.style.left
4、步骤实现
=>当开始的距离不是 0,就是有一个往回走的过程,所以我们可以获取到元素之前的初始位置
=>运动的距离不同,要同时到达目标位置,所以我们需要调整运动的速度,这个也是一个减速运动, 每次走剩余距离的 1/10
=>按照上面的方式,我们不能准确的到达目标位置,一定会出现小数0.9,而浏览器能识别的最小的单位是 1 px,所以需要我们向上取整
=>我们反方向运动的时候需要,向下取整
=>如果运动的是 opacity 属性 , 不能产生效果,存在两个原因:一个是单位,一个是opacity取值是0-1,存在小数问题
->单位解决办法:我们在运动的时候判断是不是opacity属性,如果是: 我们的就不加单位(px),反之添加
->小数问题:我们上来就需要判断一下是不是opacity属性,如果是 我们放大100倍,赋值的时候在缩小100倍
=>依旧是opacity属性在运动 , 到不了中间的位置,原因是:按照我们的计算方式 , 永远不能出现小数,所以我们可以上来就判断是不是opacity属性,如果是 我们给它放大100倍
=>同时我们这时发现,不能同时运动多个属性,需要考虑参数位的设计,以对象的方式传递参数
=>通过一个计数器,可以准确的知道什么时候运动真正的结束了
=>如果想要在结束之后做一些其他的事情,可以传入第三个参数,要是不需要我们可以不传,需要在单独加上一个判断即可
5、完整代码实现
function move(ele,options,fn){
let count = 0
for(let k in options){
// 执行一次进行一次count++
count++
// 这里判断输入的参数是否是opacity
if(k === 'opacity'){
options[k] = options[k] * 100
}
let time = setInterval(function(){
// 得到开始距离,注意传入的是字符类型
let start
// 在这里判断是否是opacity,若是*100方便计算
if(k === 'opacity'){
start = window.getComputedStyle(ele)[k] * 100
}else{
start = parseInt(window.getComputedStyle(ele)[k])
}
let distance = (options[k] - start) / 10
if(distance > 0){
// 注意取整问题,因为会在0.9哪里一直循环,定时器无法停止,所以需要我们向上取整
distance = Math.ceil(distance)
}else{
distance = Math.floor(distance)
}
// 判断如果开始距离是否等于输入的距离,从而结束定时器
if(start === options[k]){
clearInterval(time)
// 这里进行count--
count--
if(count === 0){
fn&&fn()
}
}else{
// 判断是否是opacity,若是需要除以之前*100
if(k === 'opacity'){
ele.style[k] = (distance + start) / 100
}else{
ele.style[k] = distance + start + 'px'
}
}
},20)
}
}
box.onclick = function(){
// 调用函数
move(box,{top:200,left:300,width:400,opacity:0.3},function(){
box.style.background = 'yellow'
})
}