• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
しμCīfeγ
   所以者何? 须菩提,过去心不可得,现在心不可得,未来心不可得.
博客园    首页    新随笔    联系   管理    订阅  订阅

jQuery队列操作

jQuery.queue

1、"fx"是什么?

队列动画的默认名称

队列的名字为type + "queue",默认是"fxqueue"

2、队列存储于内部jQuery._data的内部数据上

3、如果传递了数据,则直接合并到现有的数据里面

4、最后返回了一个数组

jQuery.dequeue

1、会推出队列的第一个函数,以便后面进行执行

2、同时会用当前的type名称存储一个hooks,作为最后清理data的函数,并作为每次执行时的第三个参数,这里不明白的是为什么要用Callbacks,是出于什么考虑呢?

3、并保存一个函数next,里面是出队下一函数的执行逻辑,作为执行时的第二个函数,jquery在函数执行时传入next和hooks是出于什么考虑?

4、如果是默认的fx队列,则需要再出队一次,并把开始位置减一

5、如果有出队函数,并且为fx队列,则推入"inprogress"字符串,来防止fx队列被自动出队(这里没看懂),这里折腾这一步是为了什么

6、然后删除hooks的stop函数,这里也没看懂。。。,hooks是Callback对象,哪里来的stop函数?

7、长度为0以后,调用hooks的fire函数做最后的清理

jQuery._queueHooks

1、key = type + "queueHooks";

2、如果有key对应的数据,则直接返回

     如果没有,则存入一个对象

  {

    "empty": 一个Callback对象,会把key和type对应的数据全部删除

  }

.queue

1、第一步根据type的类型来修正type的名称,如果不是字符串,则自动修复成fx

2、如果只传入了type,则直接返回$.queue定义队列

3、如果传入了空字符串,并传入了null的data,则直接把元素返回

4、如果传入的type不是字符串,则把data修正为type

5、如果传入了符合规则的type和data,则遍历元素,把每一个元素都入队对应的type和data

6、并保证每个元素都有一个hooks,这里没看懂,这么做是为什么?

7、如果为fx队列,并且为inprogress,则直接出队

.dequeue

就是遍历元素调用jQuery.dequeue方法

.promise

这是一个队列观察者函数,它监听着每个匹配元素的某一类型的队列的完成情况

<div class="wrapper">
    <img src="./img/side1.jpg" />
</div>
<script>
    !function($){
        var img = $("img");

        img.queue("test", function(){
            console.log(1);
        });

        img.dequeue("test");
        //img.dequeue("test");

        img.promise("test").done( function () {
            console.log("success");//这里不会输出 success,再把上面的注释去掉试试吧~
        });
    }(jQuery);
</script>

造成这个的原因,是因为 promise 源码中的计数器是从1开始的,为什么这么设计呢?我也不知道。。。

不过从这里和之前的代码也可以看出,queue 的这一部分主要是为 jQuery 的动画服务的,它的很多逻辑都是与 jQuery 的动画逻辑耦合的,所以 queue 这一部分其实并不适合我们在业务逻辑中单独使用

.promise()源码片段:

// Get a promise resolved when queues of a certain type
// are emptied (fx is the type by default)
promise: function( type, obj ) {
    var tmp,
        count = 1,//计数器从1开始
        defer = jQuery.Deferred(),//新的deferred对象
        elements = this,//当前的元素
        i = this.length,
        resolve = function() {
            if ( !( --count ) ) {
                defer.resolveWith( elements, [ elements ] );
            }
        };

    if ( typeof type !== "string" ) {
        obj = type;
        type = undefined;
    }
    type = type || "fx";//这里的处理逻辑与前面是一样的

    while ( i-- ) {
        tmp = jQuery._data( elements[ i ], type + "queueHooks" );
        if ( tmp && tmp.empty ) {
            count++;
            tmp.empty.add( resolve );
        }
    }
    resolve();
    return defer.promise( obj );//合并传入进来的对象
}

deferred.promise()相关的片段

// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function( obj ) {
    return obj != null ? jQuery.extend( obj, promise ) : promise;
}

再看一个 jQuery 官网给的例子

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>promise demo</title>
  <style>
  div {
    height: 50px;
    width: 50px;
    float: left;
    margin-right: 10px;
    display: none;
    background-color: #090;
  }
  </style>
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
 
<button>Go</button>
<p>Ready...</p>
<div></div>
<div></div>
<div></div>
<div></div>
 
<script>
$( "button" ).on( "click", function() {
  $( "p" ).append( "Started..." );
 
  $( "div" ).each(function( i ) {
    $( this ).fadeIn().fadeOut( 1000 * ( i + 1 ) );
  });
 
  $( "div" ).promise().done(function() {
    $( "p" ).append( " Finished! " );
  });
});
</script>
 
</body>
</html>

结果展示:http://jsfiddle.net/oh6e0uk3/

 

posted @ 2014-08-16 01:16  しμCīfeγ  阅读(1898)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3