Queue is one of the commonly used data structures, which only allows deletion (outgoing) at the front end of the table (queue head) and insertion (incoming) at the back end of the table (queue tail). The feature is first in, first out, and the first inserted element is deleted first.
In jQuery, queue module provides basic functions for animation module, which is responsible for storing animation functions, automatically queuing and executing animation functions, and ensuring the order of animation functions.
jQuery's static methods contain the following API s:
- $. queue(elem,type,data); returns or modifies the queue associated with the matching element, and returns the latest queue with the following parameters:
elem; DOM element or JavaScript object
type; queue name, default is standard animation fx
data; the queue function to be set can be empty (return queue), function (join queue), or function array (replace queue)
- $. dequeue(elem,type); the next element in the function queue used to queue and execute the match element association
elem; DOM element or JavaScript object
type; is the queue name, default to animation queue fx
writer by: Desert QQ:22969969
JQuery / $instance method (which can be called through jQuery instance):
- queue(type,data): returns the function queue of the first matching element, or modifies the function queue associated with all matching elements. The parameters are as follows:
type; queue name
Data; data is an optional function or function array, with the same parameters as the third parameter of $. queue().
- dequeue(type); queues and executes the next function in the function queue associated with all matching elements
- delay(time,type); delay the function to execute out of the queue. Insert a new function into the associated function queue by calling. queue(type,data), and delay the next function's out of queue time through setTimeout() in the function.
- clearQueue(type) |; remove all the unimplemented functions in the function queue associated with the matching element. The internal code is as follows: return this. Queue (type | "FX", []);
Here's a chestnut:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script> </head> <body> <p>123</p> <script> function f1(){console.log('f1 trigger');} //Define two test functions function f2(){console.log('f2 trigger')}; $('p').queue('test',f1); //take f1 Enter the queue with the name of test $('p').dequeue('test'); //The name of the matching element is test The function list of is queued and executed $('p').queue(f2); //take f2 Put in p In the queue of matching elements, the default is animation queue, which will be executed automatically. </script> </body> </html>
The output is as follows:
Source code analysis
The queue of jQuery is implemented based on the data cache module $. Data. When calling $. queue(), the function list is saved on the internal cache object of the corresponding DOM element with the queue name + 'queue' as the attribute, for example:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script> </head> <body> <p>123</p> <script> function f1(){console.log('f1 trigger');} $('p').queue('test',f1); </script> </body> </html>
We can get the corresponding properties directly from $. cache in the console, as follows:
document.getElementsByTagName('p')[0][$.expando] is the $. expando attribute of the P element node object in the example. The value of this attribute will be used as an attribute of $. Cache to store the data cache object corresponding to this p element (this is the content of the data cache module).
The implementation of $. queue and $. dequeue is as follows:
jQuery.extend({ /*slightly*/ queue: function( elem, type, data ) { //Returns or modifies the queue associated with the matching element. elem yes DOM Element or JavaScript Object, type Is the queue name. data Is an optional function or array of functions var q; if ( elem ) { type = ( type || "fx" ) + "queue"; //Correction parameter type,Default to animation queue fx,In parameters type Add in the back queue Indicates that this is a queue q = jQuery._data( elem, type ); //Take out parameters type If there is data in the corresponding queue, the array will be returned; otherwise, q Be equal to undefined // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { //If the data parameter if ( !q || jQuery.isArray(data) ) { //If type The queue does not exist, or type The queue exists and data Is an array q = jQuery._data( elem, type, jQuery.makeArray(data) ); //call jQuery.makeArray Put parameters data Convert to array and replace queue } else { q.push( data ); //The queue exists and data Call array if it is not an array push Method parameter data Put in queue } } return q || []; } }, dequeue: function( elem, type ) { //The next element in the function queue used to queue and perform matching element associations type = type || "fx"; //Correction parameter type,The default is"fx"; var queue = jQuery.queue( elem, type ), //Obtain elem Elemental type queue fn = queue.shift(), //call shift Method takes out the first function of the queue hooks = {}; //Store the data of the queued function at execution time // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { //If out of line is a placeholder"inprogress",Then discard another one from the queue head, only the animation queue will have placeholders"inprogress" fn = queue.shift(); } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { //If it's an animation queue queue.unshift( "inprogress" ); //Then add a placeholder at the beginning of the queue"inprogress",Indicates that the animation function is executing } jQuery._data( elem, type + ".run", hooks ); //Set internal data type+".run",Representation parameter type The corresponding queue is executing. The value is hooks,It will be passed as the second parameter to give the function of the team fn.call( elem, function() { jQuery.dequeue( elem, type ); }, hooks ); //Call function method call Execute queued function, elem Is the context of function execution, i.e. keyword this Object pointed to;The second parameter is encapsulation. jQuery.dequeue( elem, type )This function will not be executed automatically. It needs to be called manually before the queued function returns. next() } if ( !queue.length ) { //If parameters type The corresponding queue becomes empty after being queued, that is, all functions have been queued and executed jQuery.removeData( elem, type + "queue " + type + ".run", true ); //call jQuery.removeData()Method remove parameter type Corresponding data cache object handleQueueMarkDefer( elem, type, "queue" ); //Check queues associated with matching elements(type+"queue")Counter(type+"mark")Complete or not, trigger method if complete.promise()Counters in } } });
type is equal to fx by default, and jQuery's animation effect is also based on Queue. This fx is animation effect by default. For jQuery / $instance method, it is implemented by calling jQuery's static method, as follows:
jQuery.fn.extend({ queue: function( type, data ) { //Returns the function queue of the first matching element, or modifies the function queue associated with all matching elements. type Is the queue name, the default is fx. data Parameters are equivalent to jQuery.queue Medium data parameter if ( typeof type !== "string" ) { //Correction parameter When the incoming format is queue()or queue(data) (notes:data Can be a function or an array of functions)Time data = type; type = "fx"; } if ( data === undefined ) { //If no incoming data Parameters, return jQuery.queue( this[0], type ); //Then call jQuery.queue()Returns the parameter on the first matching element type Corresponding queue } return this.each(function() { //If the data parameter var queue = jQuery.queue( this, type, data ); //Called for each matching element jQuery.queue( this, type, data ),Put parameters(function)Join the team or use parameters data(Function array)Replace the queue. if ( type === "fx" && queue[0] !== "inprogress" ) { //For animation queues fx,And no animation function is executing,You are immediately queued and the animation function is executed. jQuery.dequeue( this, type ); } }); }, dequeue: function( type ) { //To queue and execute the next function in the function queue associated with the matching element return this.each(function() { jQuery.dequeue( this, type ); }); }, /*slightly*/ })