用队列模拟jquery的动画算法实例
本文实例讲述了用队列模拟jquery的动画算法。分享给大家供大家参考。具体分析如下:
Aaron最近疯狂的爱上了算法研究,估计又要死伤不少脑细胞了,我喜欢捡现成的,可以省些力气。发现他写的一段源码,运行一下,还蛮好玩的,于是拿来分析一下,一来吸收下里边的营养,二来加深一下源码学习的功力。话说这源码还真是提高js内功的一大秘决,不信,就和我一起来品味一下吧。
//立即执行函数,没有什么好说的。看下面演示 /** (function($){ //此处的$会由后面紧跟的立即执行函数的返回值提供 })(function(){ //这个函数运行的结果就是$啦 returnaQuery }())
*/ (function($){ window.$=$; })(function(){
//用来匹配ID字符串 //(?:表示这里不分组),参考正则的内容 //不过我个人认为把*改成+号会更好,因为#后至少要一个字符吧 varrquickExpr=/^(?:#([\w-]*))$/; //一看便是jquery的重度患者 functionaQuery(selector){ returnnewaQuery.fn.init(selector); }
/** *动画 *@return{[type]}[description] */ varanimation=function(){
varself={}; varQueue=[];//动画队列 varfireing=false//动画锁 varfirst=true;//通过add接口触发
vargetStyle=function(obj,attr){ returnobj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj,false)[attr]; } //这里边都是具体的动画效果,没有什么难懂的 varmakeAnim=function(element,options,func){ varwidth=options.width //包装了具体的执行算法 //css3 //setTimeout element.style.webkitTransitionDuration='2000ms'; element.style.webkitTransform='translate3d('+width+'px,0,0)';
//监听动画完结 element.addEventListener('webkitTransitionEnd',function(){ func() }); }
var_fire=function(){ //加入动画正在触发 if(!fireing){ varonceRun=Queue.shift(); if(onceRun){ //防止重复触发 fireing=true; //next onceRun(function(){ fireing=false; //这里很巧妙的产生了连环调用的效果 _fire(); }); }else{ fireing=true; } } }
returnself={ //增加队列 add:function(element,options){ //这里是整个算法的关键 //相当于往数组中添加一个函数 //[function(func){},...] //也就是_fire中的onceRun方法,func也就是在那时传进去的。 //在Aaron的编程中很喜欢用这种技巧,比如预编译什么的。 Queue.push(function(func){ makeAnim(element,options,func); });
//如果有一个队列立刻触发动画 if(first&&Queue.length){ //这个开关很好的起到了控制后面添加的元素进行排队的作用 first=false; //这里等价于直接运行_fire(); //Aaron喜欢装A,故意添加一个self.fire出来,或许他是深谋远虑 self.fire(); } }, //触发 fire:function(){ _fire(); } } }();
aQuery.fn=aQuery.prototype={ run:function(options){ animation.add(this.element,options); returnthis; } }
varinit=aQuery.fn.init=function(selector){ varmatch=rquickExpr.exec(selector); varelement=document.getElementById(match[1]) this.element=element; returnthis; } //差点小看了这一行代码 //jquery的样子学的不错 //直接aQuery.fn.init=aQuery.fn不是更好? //多一个init变量无非是想减少查询罢了,优化的思想无处不在。 init.prototype=aQuery.fn; returnaQuery; }());
//dom varoDiv=document.getElementById('div1'); //调用 oDiv.onclick=function(){
$('#div1').run({ 'width':'500' }).run({ 'width':'300' }).run({ 'width':'1000' }); };