运动透明度的模拟,都有起点,过程,以及终点。同时需要计时器来记录,开始和结束。
每次运动之前,都要清除上一次计时器的效果。否则运动会加倍。
// 参数2是对象,使用之前需要解析(遍历)
function move(ele,obj,cb){
// 清除计时器
clearInterval(ele.t);
ele.t = setInterval(() => {
var i = true;
for(var attr in obj){
if(attr == "opacity"){
var iNow = getStyle(ele,attr) * 100;
}else{
var iNow = parseInt(getStyle(ele,attr));
}
let speed = (obj[attr] - iNow)/10;
speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
// 只要有一个属性到目标,就停了,不对
// 必须所有属性到目标,才能停
// 只要有一个属性没到目标,绝对不能停
// 用状态来标记到底要不要停止计时器
// 只要有一个运动单位没到终点:绝对不能清除计时器
if(iNow !== obj[attr]){
i = false;
}
if(attr == "opacity"){
ele.style.opacity = (iNow + speed)/100;
}else{
ele.style[attr] = iNow + speed + "px";
}
}
// 每次计时器执行结束,所有单位都执行了一遍之后,状态还是true,
// 表示,没有被改成false,如果没有被改成false,表示没有属性没到终点,
//那么状态还是false就不清除
if(i){
clearInterval(ele.t);
// 用户决定在动画结束时要执行的功能,用户没传参,做个默认判断
if(cb){
cb();
}
// cb && cb();
}
}, 30);
}
function getStyle(ele,attr){
if(ele.currentStyle){
return ele.currentStyle[attr];
}else{
return getComputedStyle(ele,false)[attr];
}
}