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

 

你可能感兴趣的:(jquery)