jquery animate妙用

来源:互联网 发布:做贝斯四线谱软件 编辑:程序博客网 时间:2024/06/01 09:20
jquery中需要自定义动画时一般就会用到animate函数,但animate() 方法执行的是 CSS 属性集的自定义动画,比如 div.animate({width:300},1000);第一个参数必须是css的某个值属性。下面思考一个问题:
要求在3s内,将一个div上显示的数字从0变到100.
我们要变的是div的text,而并不是css属性,animate好像不能用。一般的思路是设置一个定时器每隔一段时间去修改一下数字,
知道显示到100时再将计时器clear掉,代码如下:

var interval=3000/100;
function dosomework(){
    ct+=interval;
    if(ct>3000) {
        clearInterval(timer);
        return;
    }
    // Todo:设置div上显示的数字为 ct/interval
}
var timer=setInterval(dosomework,interval)


可以看到这样的代码不仅比较散乱而且很不优雅,因为得自己去管理计时器,自己去控制动画每帧之间的时间间隔,而我们知道jquery  animate() 这两件事已经封装了,但前面已经说过了,animate是执行的是 CSS 属性集的动画,而我们现在并不是对css属性做动画,哪有没有什么办法呢?
我们看一下animate的一般调用方式 :
 animate(styles,speed)
animate有多种重载方式,但第一个参数都要求传一个css属性的对象,如要将left值1s内从当前值变到300,animate({left:300},1000)。
那么在现在这个问题中如果我们用animate({text:100},3000)这种方式调用该有多棒!但是,显然text并非css的属性,这个是我们自定义,等等,那animate支持我们这种自定义的属性吗?我们来换个角度,如果你是jquery的作者,在实现animate函数中要处理第一个参数时你会怎么做?  因为css属性那么多不可能一个个去验证,方便的做法是直接遍历这个对象(js天然支持对象遍历),然后看这些属性(property)的值是否是数值类型,如果是,则根据动画的总时时长算出每一帧该属性值的增量(delta),然后在每一帧回掉时通过 css({property1:  value+delta1,property2:value+delta2}) 这种方式去设置css属性。如果是这样,那我们是可以随便在styles对象中随便添加自定义属性,因为animate不会去验证这个属性是不是css的属性,那这样的话又会有两个问题: 1.应为最终会调用css(),如果我们的属性不是css支持的属性时,那css()会不会抛出异常导致脚本执行错误而中断。 
2.如果css()不会抛出异常,那我们任然需要一个修改div text的时机,这个简单,我们知道animate在每一帧动画执行结束时有个progress回调,我们可以在这个回调里面设置div的text。


那么现在还是第一个问题,比如我们自定义的属性名叫p,那么animate最终会调用css({p:100}),这会不会有问题?  我们来想想css的实现,无论如何最终转化为原生的调用会是 element.style.p=100,我们知道style是一个对象,而对一个对象obj扩展一个属性的一种方式就是直接object.xx=xx,这是完全符合js语法的,所以不会抛出异常。
算了,直观一点上个图吧,就当补补语法:


 
那jquery animate的实现是不是正如我们所想的这样呢,答案是肯定的!
经过分析jquery源码,我发现animate对第一我们传进来的css,对象是做了一个遍历,如果是数字类型,那么它会根据duration,决定将这个delta....总之和上面描述的是一样的,这也没什么奇怪的,毕竟是很直观的思路。好了,我们看看最终利用animate的代码长啥模样: 

div.animate({o:100},{duration:3000,
            progress:function(a,o){ $(this).text(o); }
        })


怎么样,惊艳吧~



1 0
原创粉丝点击