The data function in jquery is only a short 300 lines of code, very not starting point, when profiling the source, you will find that jquery as long as there is a need to save data in the place of all the time rely on this infrastructure
The animation calls the queue, and the queue calls the data interface and saves the animation data inside the queue.
So we're doing a review of the data cache.
// these may used throughout the JQuery core codebase // of the stored data // users to use New Data (); // Storage Objects // jquery Internal Private // used to store events, such as the Click event. New Data ();
There are two types of data in jquery
One is used to store data, and the corresponding objects are
Storage object: Data_user Get and set method: $.data (EL, key, value)
The other is used to store events, animated data
Storage object: Data_priv Get and set method: $._data (EL, key, value)
data_user
and data_priv
, as its name, one is user, one is jquery private, they are an instance object called data
Why should I set these 2 data interface classes?
jquery is set up to maintain a jquery data object, so
Just the interface that implements data, such as:
$ (' #aaron '). Data (' key ', ' value ')
To implement a chained. Data interface, which is simple, we can cache simple data on this object within jquery.
Method can be implemented in this way
Expands directly on the interface of the FN on the instance
function (k, v) { returnthis. each (function() { this// Save the value of interface data on the DOM object }) returnthis}
It's easy to save the data directly on the DOM object.
Of course it is possible to do this for the basic type, and if it is a reference type, what about the function object? Can you handle this?
$ (' #aaron '). Data (' NodeValue ', ' 11111 ') $ (function() { // action })
Here's the problem:
1: This will change the property value of the DOM itself, of course not to say
2: Pass but the reference type Oh, the unreliable memory recycling, maybe overflow
3: Data exposure, easy to be rewritten directly
How to solve these problems? jquery introduces the concept of data Objects
First, regardless of how the interior is implemented, first look at the properties of the node
One more gray custom key with value
Gray means that it is not possible to enumerate through a for, this setting is in ES5, which is supported directly by the API.
//If not, create oneif(!unlock) {Unlock= data.uid++; //Secure it in a non-enumerable, non-writable Property Try{descriptor[ This. expando] ={Value:unlock}; Object.defineproperties (owner, descriptor); //Support:android < 4 //Fallback to a less secure definition}Catch(e) {descriptor[ This. expando] =unlock; Jquery.extend (owner, descriptor); }}
The note is clear, the attribute is protected and cannot be rewritten.
It's OK. With such a unique bridging flag, we can do an ORM mapping, which allows the DOM to generate a one by one corresponding relationship with a data cache interface.
The data cache used by the animation queue
jquery in order to implement the chain call of the animation queue, you must first extend a method on the instance is the prototype, and then inside to invoke the underlying method
Of course, jquery is basically all the hierarchy is such a structure, in addition to the chain, but also the specific case method and the prototype method is common
// Static Jquery.extend // instance . Extend
Example methods for animations
this. Queue (Optall.queue, doanimation);
Invoking an animation-based extension interface in an instance method
JQuery.fn.extend ({ queue dequeue delay clearqueue Promise
Queuefunction(type, data) {varSetter = 2; //fix type, default to the FX that represents the jquery animation, if not "FX", //that is, for their own custom animation, generally we use "FX" is enough. if(typeofType!== "string") {Data=type; Type= "FX"; Setter--; } //only the callback of the animation //Div.slidetoggle (+); //div.slidetoggle ("fast"); //Div.animate ({left: '-=200 '},1500); //div.queue (' FX ') if(Arguments.length <setter) { returnJquery.queue ( This[0], type); } returndata = = = undefined? This : This. each (function() { //call the underlying queue //Set the animation queue cache //and returns the total number of queues varQueue = Jquery.queue ( This, type, data); //ensure a hooks for the This queueJquery._queuehooks ( This, type); //Execute animation queue directly //The dequeue operation is prevented when the function is executed, so that 2 functions are executed at the same time, and the queue is not controlled. if(Type = = = "FX" && Queue[0]!== "InProgress") { //if the queue is not locked, the dequeue is not executing at this time. Move the first function out of the queue and execute it. Jquery.dequeue ( This, type); } });},
The queue interface for the instance only makes 2 cases of judgment, one is to pass FX, one is to set the queue, the underlying or the Jquery.queue static method of processing
Analyze a set of animations:
Div.show (+);d iv.hide(+)div.show ( +)
1 interfaces with time parameters, which are sure to be animated, have multiple animation interfaces on the same interface, which means queues are needed to manage the order of execution
2 The management queue introduces the data cache, the cache needs the carrier node, so the animation's extended interface is designed to be directly linked to the DOM
The logic is definitely linear execution, show execution finished, and then remove hide execution, after the check out show execution
So how does an animation call be organized?
Theoretically 3 animations, there are 3 cached data in the cache we look under
To make it easier to see, I changed the code to add an indication that Aaron corresponds to the time
When executing div.show (3000), we look at the cache
Div.show found in 0 locations; replaced by inprogress.
Can guess the first animation is already in the beginning of the execution, then it will be in the queue with a placeholder to notify the back, I am still in the animation, the following animation first and so on
InProgress "process lock works like this:
If it is a dequeue operation, remove the lock, execute the function in the queue, and add a lock to the queue. In the case of a queue operation, to see the state of the lock, if it is locked, only the queue's add operation is performed. Dequeue is no longer called. In fact, both dequeue and queue can execute the first function in the queue. After the queue operation has finished adding queues, the Dequeue method is called to execute the function.
When executing a function with dequeue, it is possible to have 2 functions executing at this time if the dequeue is triggered by a queue. The queue loses more than half meaning (or the order is guaranteed, but 2 animations are executed at the same time). However, this lock can only guarantee that the queue will not be accidentally destroyed by the queue operation when Dequeue.
If you use 2 dequeue at the same time, it will destroy the animation effect. So I'm going to write FN in the callback function.
We started the animation the first time we did the push, which allows for better speed
. Queue (+),. Queue (3000)
if (Type = = = "FX" && Queue[0]!== "inprogress") {// If the queue is not locked, the dequeue is not executing at this time. Move out of the first function in the queue and execute it. Jquery.dequeue (this, type);}
When the first animation is finished, there must be a callback to notify this to remove the next execution in the queue, and then delete the placeholder, loop in turn
function () { if (Jquery.isfunction (opt.old)) { Opt.old.call (this); } if (opt.queue) { jquery.dequeue (this, opt.queue); }};
As a result, the execution of the animation is ultimately dependent on the queue and dequeue processing, only that the execution begins and executes a process control
How does the animation interior perform, starting from the following chapter analysis