用队列模拟jquery的动画算法实例

  本文实例讲述了用队列模拟jquery的动画算法。分享给大家供大家参考。具体分析如下:

  Aaron最近疯狂的爱上了算法研究,估计又要死伤不少脑细胞了,我喜欢捡现成的,可以省些力气。发现他写的一段源码,运行一下,还蛮好玩的,于是拿来分析一下,一来吸收下里边的营养,二来加深一下源码学习的功力。话说这源码还真是提高js内功的一大秘决,不信,就和我一起来品味一下吧。

  

复制代码 代码如下:
//立即执行函数,没有什么好说的。看下面演示

  /**

  (function($){

  //此处的$会由后面紧跟的立即执行函数的返回值提供

  })(function(){

  //这个函数运行的结果就是$啦

  return aQuery

  }())   

  */

  (function($) {

  window.$ = $;

  })(function() {

  //用来匹配ID字符串

  //(?:表示这里不分组) ,参考正则的内容

  //不过我个人认为把*改成+号会更好,因为#后至少要一个字符吧

  var rquickExpr = /^(?:#([\w-]*))$/;

  //一看便是jquery的重度患者

  function aQuery(selector) {

  return new aQuery.fn.init(selector);

  }

  /**

  * 动画

  * @return {[type]} [description]

  */

  var animation = function() {

  var self = {};

  var Queue = []; //动画队列

  var fireing = false //动画锁

  var first = true; //通过add接口触发

  var getStyle = function(obj, attr) {

  return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];

  }

  //这里边都是具体的动画效果,没有什么难懂的

  var makeAnim = function(element, options, func) {

  var width = 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) {

  var onceRun = Queue.shift();

  if (onceRun) {

  //防止重复触发

  fireing = true;

  //next

  onceRun(function() {

  fireing = false;

  //这里很巧妙的产生了连环调用的效果

  _fire();

  });

  } else {

  fireing = true;

  }

  }

  }

  return self = {

  //增加队列

  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);

  return this;

  }

  }

  var init = aQuery.fn.init = function(selector) {

  var match = rquickExpr.exec(selector);

  var element = document.getElementById(match[1])

  this.element = element;

  return this;

  }

  //差点小看了这一行代码

  //jquery的样子学的不错

  //直接aQuery.fn.init = aQuery.fn不是更好?

  //多一个init变量无非是想减少查询罢了,优化的思想无处不在。

  init.prototype = aQuery.fn;

  return aQuery;

  }());

  //dom

  var oDiv = document.getElementById('div1');

  //调用

  oDiv.onclick = function() {

  $('#div1').run({

  'width': '500'

  }).run({

  'width': '300'

  }).run({

  'width': '1000'

  });

  };

  附上html就可以自己调式了。要记得用chrome浏览哦。

  

复制代码 代码如下:
<div id="div1" style="width:100px;height:50px;background:red;cursor:pointer;color:#fff;text-align:center;line-height:50px;" data-mce-style="width: 100px; height: 50px; background: red; cursor: pointer; color: #fff; text-align: center; line-height: 50px;">点击</div>

  希望本文所述对大家的jQuery程序设计有所帮助。