jQuery1.9.1--queue队列源码分析(非动画部分)

  1 jQuery.extend({
  2         // 显示或操作在匹配元素上执行的函数队列
  3         queue: function (elem, type, data) {
  4             var queue;
  5 
  6             if (elem) {
  7                 // type没定义的话就默认使用fxqueue
  8                 type = (type || 'fx') + 'queue';
  9                 // 先获取elem上的缓存数据
 10                 queue = jQuery._data(elem, type);
 11 
 12                 if (data) {
 13                     // 如果没有缓存数据或者data是数组
 14                     // 则给elem设置缓存数据
 15                     if (!queue || jQuery.isArray(data)) {
 16                         queue = jQuery._data(elem, type, jQuery.makeArray(data));
 17                     } else {
 18                         // 否则存在缓存数据数组直接入栈
 19                         queue.push(data);
 20                     }
 21                 }
 22                 return queue || [];
 23             }
 24         },
 25         // 从队列最前端移除一个队列函数,并执行它
 26         dequeue: function (elem, type) {
 27             type = type || 'fx';
 28 
 29             var
 30             // 获取缓存队列
 31                 queue = jQuery.queue(elem, type),
 32                 startLength = queue.length,
 33             // 取得队列的第一个元素
 34                 fn = queue.shift(),
 35             // 钩子对象,如果获取不到缓存的钩子对象,就设置新的钩子对象并返回
 36                 hooks = jQuery._queueHooks(elem, type),
 37             // 用来执行下一个队列
 38                 next = function () {
 39                     jQuery.dequeue(elem, type);
 40                 };
 41 
 42             // 如果第一个元素是"inprogress",取下一个元素,长度相应减1
 43             if (fn === 'inprogress') {
 44                 fn = queue.shift();
 45                 startLength--;
 46             }
 47 
 48             // 为钩子对象添加cur方法
 49             hooks.cur = fn;
 50             // 如果此时fn不为null || false || undefined
 51             if (fn) {
 52                 // 如果type为“fx”,给队列添加"inprogress",防止自动出列(dequeue)
 53                 if (type === 'fx') {
 54                     queue.unshift('inprogress');
 55                 }
 56 
 57                 // 删除上一个队列的stop函数
 58                 delete hooks.stop;
 59                 // 执行fn函数,并且把下一个队列函数设置为fn的第一个参数
 60                 /*
 61                 可以这样使用:
 62                  $(document.body).queue('test', function(next){
 63                  console.log(11);
 64                  next();
 65                  });
 66                  $(document.body).queue('test', function(){
 67                  console.log(22);
 68                  });
 69                  $(document.body).dequeue('test');
 70                  */
 71                 fn.call(elem, next, hooks);
 72             }
 73 
 74             // 如果队列长度为0且存在钩子对象,则删除缓存
 75             if (!startLength && hooks) {
 76                 hooks.empty.fire();
 77             }
 78         },
 79         // 私有方法,生成一个队列钩子对象(即从缓存数据中获取的队列钩子)
 80         // 或者设置缓存队列钩子对象,这个对象的empty属性是一个Callbacks对象,这里的作用是删除缓存队列和缓存队列钩子的数据
 81         _queueHooks: function (elem, type) {
 82             var key = type + 'queueHooks';
 83             return jQuery._data(elem, key) || jQuery._data(elem, key, {
 84                 empty: jQuery.Callbacks('once memory').add(function () {
 85                     jQuery._removeData(elem, type + 'queue');
 86                     jQuery._removeData(elem, key);
 87                 })
 88             });
 89         }
 90     });
 91 
 92     jQuery.fn.extend({
 93         queue: function (type, data) {
 94             var setter = 2;
 95 
 96             if (typeof type !== 'string') {
 97                 data = type;
 98                 type = 'fx';
 99                 setter--;
100             }
101 
102             /*
103             当满足这个条件的有以下几个情况:
104             1.没有参数
105             2.参数只有一个,且type是字符串
106              */
107             if (arguments.length < setter) {
108                 return jQuery.queue(this[0], type);
109             }
110 
111             // 其他情况
112             return data === undefined ?
113                 this :
114                 this.each(function () {
115                     var queue = jQuery.queue(this, type, data);
116 
117                     jQuery._queueHooks(this, type);
118 
119                     // 如果是动画队列且第一个元素不是"inprogres",
120                     // 就出列并执行下一个元素
121                     if (type === 'fx' && queue[0] !== 'inprogress') {
122                         jQuery.dequeue(this, type);
123                     }
124                 });
125         },
126         dequeue: function (type) {
127             return this.each(function () {
128                 jQuery.dequeue(this, type);
129             });
130         },
131         // TODO
132         delay: function (time, type) {
133             time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
134             type = type || 'fx';
135 
136             return this.queue(type, function (next, hooks) {
137                 var timeout = setTimeout(next, time);
138                 hooks.stop = function () {
139                     clearTimeout(timeout);
140                 };
141             });
142         },
143         clearQueue: function (type) {
144             return this.queue(type || 'fx', []);
145         },
146         promise: function (type, obj) {
147             var tmp,
148                 count = 1,
149                 defer = jQuery.Deferred(),
150                 elements = this,
151                 i = this.length,
152                 resolve = function () {
153                     if (!(--count)) {
154                         defer.resolveWith(elements, [elements]);
155                     }
156                 };
157 
158             if (typeof type !== 'string') {
159                 obj = type;
160                 type = undefined;
161             }
162             type = type || 'fx';
163 
164             while (i--) {
165                 tmp = jQuery._data(elements[i], type + 'queueHooks');
166                 if (tmp && tmp.empty) {
167                     count++;
168                     tmp.empty.add(resolve);
169                 }
170             }
171             resolve();
172             return defer.promise(obj);
173         }
174     });
View Code
原文地址:https://www.cnblogs.com/webFrontDev/p/3141050.html