I found the jQuery.com document on queue()
/dequeue()
is too simple to understand. What exactly are queues in jQuery? How should I use them?
JavaScript Queue is one of the linear data structures used to store data in the memory. We can define a queue as a linear data structure that stores data sequentially based on the First In First Out (FIFO) manner. So, the data which is inserted first will be removed from the queue first.
The jQuery animate() method is used to create custom animations. Syntax: $(selector).animate({params},speed,callback);
.queue()
and .dequeue()
Queues in jQuery are used for animations. You can use them for any purpose you like. They are an array of functions stored on a per element basis, using jQuery.data()
. They are First-In-First-Out (FIFO). You can add a function to the queue by calling .queue()
, and you remove (by calling) the functions using .dequeue()
.
To understand the internal jQuery queue functions, reading the source and looking at examples helps me out tremendously. One of the best examples of a queue function I've seen is .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
The default queue in jQuery is fx
. The default queue has some special properties that are not shared with other queues.
$(elem).queue(function(){});
the fx
queue will automatically dequeue
the next function and run it if the queue hasn't started. dequeue()
a function from the fx
queue, it will unshift()
(push into the first location of the array) the string "inprogress"
- which flags that the queue is currently being run.fx
queue is used by .animate()
and all functions that call it by default.NOTE: If you are using a custom queue, you must manually .dequeue()
the functions, they will not auto start!
You can retrieve a reference to a jQuery queue by calling .queue()
without a function argument. You can use the method if you want to see how many items are in the queue. You can use push
, pop
, unshift
, shift
to manipulate the queue in place. You can replace the entire queue by passing an array to the .queue()
function.
Quick Examples:
// 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
) queue example: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');
I developed an $.ajaxQueue()
plugin that uses the $.Deferred
, .queue()
, and $.ajax()
to also pass back a promise that is resolved when the request completes. Another version of $.ajaxQueue
that still works in 1.4 is posted on my answer to 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);
I have now added this as an article on learn.jquery.com, there are other great articles on that site about queues, go look.
To understand queue method, you have to understand how jQuery does animation. If you write multiple animate method calls one after the other, jQuery creates an 'internal' queue and adds these method calls to it. Then it runs those animate calls one by one.
Consider following code.
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); }
The 'queue'/'dequeue' method gives you control over this 'animation queue'.
By default the animation queue is named 'fx'. I have created a sample page here which has various examples which will illustrate how the queue method could be used.
http://jsbin.com/zoluge/1/edit?html,output
Code for above sample page:
$(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); }
Now you may ask, why should I bother with this queue? Normally, you wont. But if you have a complicated animation sequence which you want to control, then queue/dequeue methods are your friend.
Also see this interesting conversation on jQuery group about creating a complicated animation sequence.
http://groups.google.com/group/jquery-en/browse_thread/thread/b398ad505a9b0512/f4f3e841eab5f5a2?lnk=gst
Demo of the animation:
http://www.exfer.net/test/jquery/tabslide/
Let me know if you still have questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With