zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/webFrontDev/p/3141050.html
Copyright © 2011-2022 走看看