jQuery中的队列是什么?

时间:2009-06-29 13:04:08

标签: jquery

我发现queue() / dequeue()上的jQuery.com文档太简单了。 jQuery中的队列究竟是什么?我应该如何使用它们?

6 个答案:

答案 0 :(得分:488)

jQuery .queue().dequeue()

的用法 jQuery中的

Queues用于动画。您可以将它们用于任何您喜欢的目的。它们是使用jQuery.data()基于每个元素存储的函数数组。它们是先进先出(FIFO)。您可以通过调用.queue()向队列中添加一个函数,然后使用.dequeue()删除(通过调用)函数。

要理解内部jQuery队列函数,reading the source并查看示例可以极大地帮助我。我见过的队列函数的最好例子之一是.delay()

$.fn.delay = function( time, type ) {
  time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
  type = type || "fx";

  return this.queue( type, function() {
    var elem = this;
    setTimeout(function() {
      jQuery.dequeue( elem, type );
    }, time );
  });
};

默认队列 - fx

jQuery中的默认队列是fx。默认队列具有一些不与其他队列共享的特殊属性。

  1. 自动启动:调用$(elem).queue(function(){});时,fx队列将自动dequeue下一个功能,如果队列尚未启动,则运行它。
  2. 'inprogress'sentinel :每当dequeue()来自fx队列的函数时,它将unshift()(推入阵列的第一个位置)字符串"inprogress" - 标记队列当前正在运行。
  3. 这是默认值! fx队列由.animate()和默认调用它的所有函数使用。
  4. 注意:如果您使用的是自定义队列,则必须手动.dequeue()这些功能,它们不会自动启动!

    检索/设置队列

    您可以通过在没有函数参数的情况下调用.queue()来检索对jQuery队列的引用。如果要查看队列中有多少项,可以使用该方法。您可以使用pushpopunshiftshift来操作队列。您可以通过将数组传递给.queue()函数来替换整个队列。

    快速示例:

    // lets assume $elem is a jQuery object that points to some element we are animating.
    var queue = $elem.queue();
    // remove the last function from the animation queue.
    var lastFunc = queue.pop(); 
    // insert it at the beginning:    
    queue.unshift(lastFunc);
    // replace queue with the first three items in the queue
    $elem.queue(queue.slice(0,3)); 
    

    动画(fx)队列示例:

    Run example on jsFiddle

    $(function() {
        // lets do something with google maps:
        var $map = $("#map_canvas");
        var myLatlng = new google.maps.LatLng(-34.397, 150.644);
        var myOptions = {zoom: 8, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
        var geocoder = new google.maps.Geocoder();
        var map = new google.maps.Map($map[0], myOptions);
        var resized = function() {
            // simple animation callback - let maps know we resized
            google.maps.event.trigger(map, 'resize');
        };
    
        // wait 2 seconds
        $map.delay(2000);
        // resize the div:
        $map.animate({
            width: 250,
            height: 250,
            marginLeft: 250,
            marginTop:250
        }, resized);
        // geocode something
        $map.queue(function(next) {
            // find stackoverflow's whois address:
          geocoder.geocode({'address': '55 Broadway New York NY 10006'},handleResponse);
    
          function handleResponse(results, status) {
              if (status == google.maps.GeocoderStatus.OK) {
                  var location = results[0].geometry.location;
                  map.setZoom(13);
                  map.setCenter(location);
                  new google.maps.Marker({ map: map, position: location });
              }
              // geocoder result returned, continue with animations:
              next();
          }
        });
        // after we find stack overflow, wait 3 more seconds
        $map.delay(3000);
        // and resize the map again
        $map.animate({
            width: 500,
            height: 500,
            marginLeft:0,
            marginTop: 0
        }, resized);
    });
    

    另一个自定义队列示例

    Run example on jsFiddle

    var theQueue = $({}); // jQuery on an empty object - a perfect queue holder
    
    $.each([1,2,3],function(i, num) {
      // lets add some really simple functions to a queue:
      theQueue.queue('alerts', function(next) { 
        // show something, and if they hit "yes", run the next function.
        if (confirm('index:'+i+' = '+num+'\nRun the next function?')) {
          next();
        }
      }); 
    });
    
    // create a button to run the queue:
    $("<button>", {
      text: 'Run Queue', 
      click: function() { 
        theQueue.dequeue('alerts'); 
      }
    }).appendTo('body');
    
    // create a button to show the length:
    $("<button>", {
      text: 'Show Length', 
      click: function() { 
        alert(theQueue.queue('alerts').length); 
      }
    }).appendTo('body');
    

    排队Ajax呼叫:

    我开发了一个$.ajaxQueue()插件,该插件使用$.Deferred.queue()$.ajax()来传回请求完成时已解析的promise$.ajaxQueue的另一个版本仍然适用于1.4版,已发布在我对Sequencing Ajax Requests

    的回复中
    /*
    * jQuery.ajaxQueue - A queue for ajax requests
    * 
    * (c) 2011 Corey Frang
    * Dual licensed under the MIT and GPL licenses.
    *
    * Requires jQuery 1.5+
    */ 
    (function($) {
    
    // jQuery on an empty object, we are going to use this as our Queue
    var ajaxQueue = $({});
    
    $.ajaxQueue = function( ajaxOpts ) {
        var jqXHR,
            dfd = $.Deferred(),
            promise = dfd.promise();
    
        // queue our ajax request
        ajaxQueue.queue( doRequest );
    
        // add the abort method
        promise.abort = function( statusText ) {
    
            // proxy abort to the jqXHR if it is active
            if ( jqXHR ) {
                return jqXHR.abort( statusText );
            }
    
            // if there wasn't already a jqXHR we need to remove from queue
            var queue = ajaxQueue.queue(),
                index = $.inArray( doRequest, queue );
    
            if ( index > -1 ) {
                queue.splice( index, 1 );
            }
    
            // and then reject the deferred
            dfd.rejectWith( ajaxOpts.context || ajaxOpts,
                [ promise, statusText, "" ] );
    
            return promise;
        };
    
        // run the actual query
        function doRequest( next ) {
            jqXHR = $.ajax( ajaxOpts )
                .done( dfd.resolve )
                .fail( dfd.reject )
                .then( next, next );
        }
    
        return promise;
    };
    
    })(jQuery);
    

    我现在已经在learn.jquery.com上添加了这篇文章,该网站上还有其他关于队列的精彩文章,请查看。

答案 1 :(得分:42)

要理解队列方法,您必须了解jQuery如何进行动画制作。如果你一个接一个地编写多个animate方法调用,jQuery会创建一个“内部”队列并将这些方法调用添加到它。然后它逐个运行那些动画调用。

请考虑以下代码。

function nonStopAnimation()
{
    //These multiple animate calls are queued to run one after
    //the other by jQuery.
    //This is the reason that nonStopAnimation method will return immeidately
    //after queuing these calls. 
    $('#box').animate({ left: '+=500'}, 4000);
    $('#box').animate({ top: '+=500'}, 4000);
    $('#box').animate({ left: '-=500'}, 4000);

    //By calling the same function at the end of last animation, we can
    //create non stop animation. 
    $('#box').animate({ top: '-=500'}, 4000 , nonStopAnimation);
}

'queue'/'dequeue'方法让您可以控制这个'动画队列'。

默认情况下,动画队列名为“fx”。我在这里创建了一个示例页面,其中包含各种示例,这些示例将说明如何使用队列方法。

http://jsbin.com/zoluge/1/edit?html,output

以上示例页面的代码:

$(document).ready(function() {
    $('#nonStopAnimation').click(nonStopAnimation);

    $('#stopAnimationQueue').click(function() {
        //By default all animation for particular 'selector'
        //are queued in queue named 'fx'.
        //By clearning that queue, you can stop the animation.
        $('#box').queue('fx', []);
    });

    $('#addAnimation').click(function() {
        $('#box').queue(function() {
            $(this).animate({ height : '-=25'}, 2000);
            //De-queue our newly queued function so that queues
            //can keep running.
            $(this).dequeue();
        });
    });

    $('#stopAnimation').click(function() {
        $('#box').stop();
    });

    setInterval(function() {
        $('#currentQueueLength').html(
         'Current Animation Queue Length for #box ' + 
          $('#box').queue('fx').length
        );
    }, 2000);
});

function nonStopAnimation()
{
    //These multiple animate calls are queued to run one after
    //the other by jQuery.
    $('#box').animate({ left: '+=500'}, 4000);
    $('#box').animate({ top: '+=500'}, 4000);
    $('#box').animate({ left: '-=500'}, 4000);
    $('#box').animate({ top: '-=500'}, 4000, nonStopAnimation);
}

现在你可能会问,我为什么要打扰这个队列?通常,你不会。但是如果你想要控制一个复杂的动画序列,那么队列/出队方法就是你的朋友。

另见jQuery小组关于创建复杂动画序列的有趣对话。

http://groups.google.com/group/jquery-en/browse_thread/thread/b398ad505a9b0512/f4f3e841eab5f5a2?lnk=gst

动画演示:

http://www.exfer.net/test/jquery/tabslide/

如果您仍有疑问,请与我联系。

答案 2 :(得分:20)

队列中的多个对象动画

以下是队列中多个对象动画的简单示例。

Jquery让我们只对一个对象进行排队。但在动画功能中我们可以访问其他对象。在这个例子中,我们在#box对象上构建队列,同时为#box1和#box2对象设置动画。

将队列视为一系列函数。因此,您可以将队列操作为数组。您可以使用push,pop,unshift,shift来操作队列。在这个例子中,我们从动画队列中删除最后一个函数并将其插入开头。

当我们完成后,我们通过dequeue()函数启动动画队列。

See at jsFiddle

HTML:

  <button id="show">Start Animation Queue</button>
  <p></p>
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="q"></div>

JS:

$(function(){

 $('#q').queue('chain',function(next){  
      $("#box2").show("slow", next);
  });


  $('#q').queue('chain',function(next){  
      $('#box1').animate(
          {left: 60}, {duration:1000, queue:false, complete: next}
      )
  });    


  $('#q').queue('chain',function(next){  
      $("#box1").animate({top:'200'},1500, next);
  });


  $('#q').queue('chain',function(next){  
      $("#box2").animate({top:'200'},1500, next);
  });


  $('#q').queue('chain',function(next){  
      $("#box2").animate({left:'200'},1500, next);
  });

  //notice that show effect comes last
  $('#q').queue('chain',function(next){  
      $("#box1").show("slow", next);
  });

});

$("#show").click(function () {
    $("p").text("Queue length is: " + $('#q').queue("chain").length);

    // remove the last function from the animation queue.
    var lastFunc = $('#q').queue("chain").pop();
    // insert it at the beginning:    
    $('#q').queue("chain").unshift(lastFunc);

    //start animation queue
    $('#q').dequeue('chain');
});

的CSS:

        #box1 { margin:3px; width:40px; height:40px;
                position:absolute; left:10px; top:60px; 
                background:green; display: none; }
        #box2 { margin:3px; width:40px; height:40px;
                position:absolute; left:100px; top:60px; 
                background:red; display: none; }
        p { color:red; }  

答案 3 :(得分:15)

它允许您排队动画...例如,而不是此

$('#my-element').animate( { opacity: 0.2, width: '100px' }, 2000);

使元素淡化并同时使宽度100 px 。使用队列可以暂存动画。所以一个接一个完成。

$("#show").click(function () {
    var n = $("div").queue("fx");
    $("span").text("Queue length is: " + n.length);
});

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

来自http://docs.jquery.com/Effects/queue

的示例

答案 4 :(得分:8)

这个帖子帮助了我很多问题,但是我以不同的方式使用了$ .queue,并且认为我会在这里发布我想出的内容。我需要的是要触发的一系列事件(帧),但是要动态构建的序列。我有一个可变数量的占位符,每个占位符都应包含一个动画序列的图像。数据保存在一个数组数组中,因此我循环遍历数组,为每个占位符构建每个序列,如下所示:

/* create an empty queue */
var theQueue = $({});
/* loop through the data array */
for (var i = 0; i < ph.length; i++) {
    for (var l = 0; l < ph[i].length; l++) {
        /* create a function which swaps an image, and calls the next function in the queue */
        theQueue.queue("anim", new Function("cb", "$('ph_"+i+"' img').attr('src', '/images/"+i+"/"+l+".png');cb();"));
        /* set the animation speed */
        theQueue.delay(200,'anim');
    }
}
/* start the animation */
theQueue.dequeue('anim');

这是我已经达到的脚本的简化版本,但是应该显示原理 - 当一个函数被添加到队列时,它是使用Function构造函数添加的 - 这样函数可以使用来自的变量动态编写循环。注意函数传递next()调用的参数的方式,并在最后调用它。在这种情况下,函数没有时间依赖性(它不使用$ .fadeIn或类似的东西),所以我使用$ .delay错开帧。

答案 5 :(得分:-1)

功能makeRedmakeBlack使用queuedequeue互相执行。结果是'#wow'元素不断闪烁。

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
          $('#wow').click(function(){
            $(this).delay(200).queue(makeRed);
            });
          });

      function makeRed(){
        $('#wow').css('color', 'red');
        $('#wow').delay(200).queue(makeBlack);
        $('#wow').dequeue();
      }

      function makeBlack(){
        $('#wow').css('color', 'black');
        $('#wow').delay(200).queue(makeRed);
        $('#wow').dequeue();
      }
    </script>
  </head>
  <body>
    <div id="wow"><p>wow</p></div>
  </body>
</html>