jQuery队列方法

发布于 2016-10-11 22:08 阅读数 96

本文必须得到作者授权后,方可转载,摘要引流随意。
By 依韵 , From https://blog.cdswyda.com/post/20161011

jQueryObject.queue()

根据参数的不同,jQueryObject.queue()有以下几种使用方法:

jQueryObject.queue( [queueName ] )

此方法可显示在选定元素上的将要执行的函数队列,返回值类型为数组。

参数queueName表示队列名称,默认为'fx',即默认的jQuery队列,可省略。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    // 页面上有一个div,样式display:none 
    var $div = $("#divtest");
    $('body').on('click', function() {
        // 未绑定时 显示其队列
        console.log('start', $div.queue());

        $div.show(2000)
            .animate({
                left: "+=200"
            }, 2000)
            .slideToggle(1000)
            .slideToggle("fast")
            .animate({
                left: "-=200"
            }, 1500)
            .hide("slow")
            .show(1200);

        // 显示将要执行的队列
        console.log('end', $div.queue(), $div.queue().length);
    });
    // 结果如下:
    // start []
    // end ["inprogress", function, function, function, function, function, function] 7

点击页面后,加入click事件函数,第一次显示时还未在div上绑定动画效果,故没有要执行的函数,其队列为一个空数组。

之后在这个div上指定了七个动画,再次显示队列时,队列结果为一个数组,长度为7,第一个为“inprogress”表示在执行还未完毕,之后是6个待执行的function。

队列数组是在动态变化的,当执行情况发生改变时,队列结果也随之改变。请看下面例子:

jQueryObject.queue( [queueName ], newQueue )

可以用一个新的队列函数来替换当前队列。

参数queueName string类型 表示队列名称,默认为'fx'

参数newQueue 一个数组 表示新队列,用于替换当前队列的内容

仍用之前的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    var $div = $("div");
    $('body').on('click', function() {   
        $div.show(2000)
            .animate({
                left: "+=200"
            }, 2000)
            .slideToggle(1000)
            .slideToggle("fast")
            .animate({
                left: "-=200"
            }, 1500)
            .hide("slow")
            .show(1200);
        
        // 替换当前队列
        $div.queue('fx',[]);
        console.log('替换后队列', $div.queue());
        // []
    });

结果为:

绑定动画后,又立即替换当前队列(当前队列为之后的6个动画),由于这里替换的为一个空队列。所以当当前的inprogress执行完毕后,之后就没有等待的队列内容了。所以动画也就停止了。

还可以指定新的函数队列:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    var $div = $("div");
    $div.queue("myQueue", [
        function(next) {
            alert("队列函数1"); 
            next();
        },
        function(next) {
            alert("队列函数2");
            next();
        },
        function(next) {
            alert("队列函数3");
            next();
        }
    ]);
    // 显示在div上的队列
    console.log($div.queue());          // []
    console.log($div.queue('myQueue')); // [function, function, function]

由于之前不存在“myQueue”,原队列为空,所以替换队列的方法实际上时添加了一个新队列,名为:“muQueue”,其中有三个在队列中等待执行的函数。

$div.queue()显示默认的名为“fx”队列,由于其中没有排队中的函数,故为一个空数组。

$div.queue('myQueue')显示默认的名为“myQueue”队列,队列内容就是我们为其添加的三个函数。

jQueryObject.queue( [queueName ], callback )

将添加一个新函数到队列中。

参数queueName string类型 表示队列名称,默认为'fx',可省略。

参数callback 一个函数 表示将要添加到队列中的函数。

1
    $div.slideUp(1000).fadeIn(3000);

当这个语句被执行,这个元素开始立即做滑动动画,只有当滑动动画完成后才会执行渐入动画,也就是渐入动画还在队列中等待。

使用.queue方法,可以将一个函数加到队列末端:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    $div.slideUp(1000)
        .queue('fx', function() {
            $div.text('滑动完成!');
            $(this).dequeue();
        })
        .fadeIn(3000)
        .queue('fx', function() {
            $div.text('渐入完成!');
            $(this).dequeue();
        });

    // 等价于下面这种写法
    $div.slideUp(1000, function() {
            $div.text('滑动完成!');
        })
        .fadeIn(3000, function() {
            $div.text('渐入完成!');           
        });

该函数的功能类似于在动画方法中提供了回调函数,但是不要求在动画执行时指定回调函数。

值得注意的是,当使用.queue()添加一个函数的时候,我们应该保证在函数最后调用了 jQuery.dequeue(),这样就能让队列中的其它函数按顺序执行。

从jQuery 1.4开始,向队列中追加函数时,可以向该函数中传入next,作为第一个参数。当此函数调用时,会自动让队列中的下一个出列,来保证队列的正确移动。如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    $div.slideUp(1000)
        .queue('fx', function(next) {
            $div.text('滑动完成!');
            next();    // 传入next,并调用next等同于下面的dequeue
            // $(this).dequeue();
        })
        .fadeIn(3000)
        .queue('fx', function(next) {
            $div.text('渐入完成!');
            next();
            // $(this).dequeue();
        });

jQueryObject.dequeue()

顾名思义:即为出列,在jquery中队列的成员都是函数,出列的同时其也将被调用。

拿之前的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    var $div = $("div");
    $div.queue("myQueue", [
        function(next) {
            alert("队列函数1"); 
            next();
        },
        function(next) {
            alert("队列函数2");
            next();
        },
        function(next) {
            alert("队列函数3");
            next();
        }
    ]);
    // 显示在div上的队列
    console.log($div.queue());          // []
    console.log($div.queue('myQueue')); // [function, function, function]

仅仅这样在页面上是没有任何反应的。也就是说虽然排好了队伍,但是队伍还没开始动。就好像去医院挂号排队,但是医院还没上班,都还在排队等待的状态。这时候就需要deQueue调用一下。

开始页面是没有反应的,我们在控制台执行了$div.dequeue('myQueue');命令后,队列才开始移动,依次弹出队列函数1、2、3。

前面讲到了使用.queue()方法添加的函数内部的最后需要使用deQueue来使得队列中的其他函数顺序运行。

.dequeue()调用时,队列中的最前端的下一个队列函数被移出队列,并被执行。

“myQueue”是一个队列。首次执行$div.dequeue('myQueue');时,队列的最前端即为队列函数1,所以队列函数1出列并被执行,此时队列最前端变成了队列函数2。由于在第一个函数中传入了next,并在它函数内部的最后调用了next,故使得队列开始自动移动。

在每个队列函数内部最后使用deQueue()或者传入next并调用,都能使队列自动移动。

如果两者都没使用,那么必须一次一次手动调用deQueue()来使队列移动。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    var $div = $("div");
    $div.queue("myQueue", [
        function() {
            alert("队列函数1");                     
        },
        function(next) {
            alert("队列函数2");                 
        },
        function(next) {
            alert("队列函数3");                 
        }
    ]);         

为了保证队列能够自动移动,请务必在使用.queue()方法添加的队列函数中调用.deQueue()方法或在队列函数中传入next,并调用。

jQueryObject.clearQueue

clearQueue([queueName])

参数queueName string类型 表示队列名称,默认为'fx',可省略。

清空对象上尚未执行的所有队列函数。

不传递参数时(即队列名为“fx”,jQuery默认都将队列函数加入此队列),.clearQueue方法类似于stop(true)

不同之处:

1、stop(true)可以使得其在当前状态立即停止。而.clearQueue会等待当前动作完成后停止。

2、stop(true)只能清空动画队列,而.clearQueue可清空在此对象上指定队列名下的所有队列函数。jQuery API文档上如此描述,实际测试两者都清空了fx下的所有队列函数,无论是否为动画。测试版本2.2.3和3.1.1)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    var $div = $("div");
    $('#start').on('click', function() {
        (function go() {
            $div.queue(function(next) {
                    $div.addClass('yellow');
                    next();
                })
                .animate({
                    left: "+=200"
                }, 2000)
                .animate({
                    left: "-=200"
                }, 1500)
                .queue(function(next) {
                    $div.removeClass('yellow');
                    next();
                })
                .animate({
                    top: "+=10"
                }, go);

        })();
    });
    // clearQueue清空
    $('#end1').on('click', function() {
        $div.clearQueue();
        console.log($div.queue());
        
    });
    // stop(true)清空
    $('#end2').on('click', function() {       
        $div.stop(true);
        console.log($div.queue());        
    });     

stop(true)使得其在当前状态立即停止:

.clearQueue会等待当前动作完成后停止:

$.queue()和$.dequeue()

除了jQuery对象上有上面介绍的队列方法之外,在jQuery本身也有queuedequeue这两个方法。用法和jQuery对象上的类似,只需要将第一个参数传入要操作的dom对象即可,其他参数依次后推。

我们使用$.queue()方法对我们的第一个示例代码进行改写:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    // 页面上有一个div,样式display:none 
    var $div = $("#divtest");
    $('body').on('click', function() {
            // 未绑定时 显示其队列
            console.log('start', $.queue($div[0],'fx'));    // $.queue($div[0],'fx') 替换了$div.queue()
            // console.log('start', $div.queue());

            $div.show(2000)
                .animate({
                    left: "+=200"
                }, 2000)
                .slideToggle(1000)
                .slideToggle("fast")
                .animate({
                    left: "-=200"
                }, 1500)
                .hide("slow")
                .show(1200);

            // 显示将要执行的队列
            console.log('end', $.queue($div[0],'fx'), $.queue($div[0],'fx').length);
            // console.log('end', $div.queue(), $div.queue().length);
        });
        // 结果如下:
        // start []
        // end ["inprogress", function, function, function, function, function, function] 7

$.dequeue()也是相同的,下面我们使用$.dequeue来触发队列移动。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    var $div = $("#divtest");
    
    // 给div添加一个名为myQueue的队列
    $div.queue("myQueue", [
        function(next) {
            alert("队列函数1");
            next();
        },
        function(next) {
            alert("队列函数2");
            next();
        },
        function(next) {
            alert("队列函数3");
            next();
        }
    ]);

前面我们演示了使用$div.dequeue来使队列移动,使用$.dequeue( el , [queueName ])也同样可以实现。

直接挂在jQuery对象本身上的方法属于低级API,而在jQuery对象上使用的方法属于高级API,低级API通常作为工具方法或为高级API服务的,例如这里的jQuery对象上的.queue方法内部实际就是调用的$.queue并将第一个参数替换成了this

我们在使用时,操作具体dom元素时,尽可能使用jQuery对象上的方法,这样清楚明了,可读性较高。


Comments
Write a Comment