以前学了js的动画效果,当时看了别人的实现思路,以为自己听懂了,然后没太管,感觉太简单,但是这次做的一个项目中要用到动画效果,想着如果自己都手写一下就太麻烦了,于是想着自己实现一下这个完美运动框架,但是实现的过程中发现,其实没有那么简单,要写一个完美运动框架,那么他就要适合改变各种属性,那么他的参数必须有两个,一个是要改变的元素,第二个是要改变的属性,为了实现多个属性同时运动,我们的第二个参数需要是JSON格式的数据,第三个参数可以是一个回调函数,就是当我们达到目标值后,要执行的函数,看就是下面这个样子

function startMove (obj, json, fn)

代码中要获取一个元素的属性值,需要有这样的一个函数

function getStyle (obj, attr)
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}

这里关于

obj.currentStyle和getComputedStyle可以参考下面这篇文章

​张鑫旭写的获取元素CSS值之getComputedStyle方法熟悉​​​这篇文章,
看了之后会有一个很好的理解,我理解大概就是这么个意思
getComputedStyle是可以把一个元素所有的样式获取出来;而元素的style只能获取到元素的style属性里面的值,如果元素的样式是外联的,就没办法获取了。

currentStyle是ie出的一个产物,作用和getComputedStyle一样


接着又回过头来讲我们运动框架,先上一般别人的代码

function startMove(obj, json, fn)
clearInterval(obj.timer);
obj.timer = setInterval(function (){
var bStop = true;

//这一次运动就结束了——所有的值都到达了
for(var attr in json) {

//1.取当前的值
var iCur = 0;

if(attr == 'opacity') {
iCur = parseInt(parseFloat(getStyle(obj, attr))*100);
} else {
iCur = parseInt(getStyle(obj, attr));
}

//2.算速度
var iSpeed = (json[attr]-iCur)/8;

iSpeed = iSpeed > 0?Math.ceil(iSpeed):Math.floor(iSpeed);

//3.检测停止
if(iCur!=json[attr]) {
bStop=false;
}

if(attr=='opacity') {
obj.style.filter='alpha(opacity:'+(iCur+iSpeed)+')';
obj.style.opacity=(iCur+iSpeed)/100;
} else {
obj.style[attr]=iCur+iSpeed+'px';
}

}

if(bStop) {
clearInterval(obj.timer);

if(fn){
fn();
}
}

}, 30)
}

用起来,是没有问题,可是元素要改变的属性如果是opacity的话,他就必须要传入0-100之间的值,这与我们平时写的opacity的值不一样,所以我自己写了一个

function startMove (obj, json, fn)
clearInterval(obj.timer);
obj.timer = setInterval(function ()
var bStop = true,
cur,
speed;

for (var attr in json) {
if (attr === "opacity") {
cur = parseInt((getStyle(obj, attr))*100);
//让json[attr]和cur有朝一日能相等
speed = (parseInt(json[attr]*100) - cur)/8;
} else {
cur = parseInt(getStyle(obj, attr));
speed = (json[attr] - cur)/8;
}

speed = speed > 0?Math.ceil(speed):Math.floor(speed);

if (cur != json[attr]) {
bStop = false;
}

if (attr === "opacity") {
obj.style.opacity = (cur + speed)/100;
} else {
obj.style[attr] = cur + speed + "px";
}
}

if(bStop) {
clearInterval(obj.timer);
if (fn) {
fn();
}
}
}, 1000);
}

我自己写的这个如果属性是opacity就可以写成0到1之间的值了,这里我总结了一条很重要的一点就是动画的当前值加上速度值,一定要在某个阶段等于目标值,我在代码中还专门为那一行做了注释,为了实现这一目标,我们在速度值的时候因为是有小数的存在,一定要在把他变为整数,这样才会到最后为1的时候精确控制目标元素的值,目标元素的值必须为整数,如果不是整数就必须做上述代码中的opacity的值*100然后在取整的操作,就是还原到整数那个阶段,但是这样其实也不太完美,如果opacity的值的小数位大于两位的话,他就有可能不会完美的到达目标值。

希望看到的人赐教。