The biggest update in version 1.5 is a complete rewrite of AJAX, providing greater scalability. However, due to energy and space constraints, the analysis of the new AJAX will be postponed to another time. This article will briefly introduce the detailed improvements.
jQuery._Deferred and jQuery.Deferred
First of all, I have to talk about these two new things, because they exist as infrastructure. If these two things are not explained clearly, some problems cannot be explained at all. .
First of all, jQuery.Deferred is an enhanced version of jQuery._Deferred, so for this problem, starting with jQuery._Deferred can explain most of the problem.
What is Deferred? Literally, my first reaction was "lazy loading". The first letter in capital letters should be the definition of "type", so this is probably a type that "transparently provides lazy loading function". However, in fact, although it does have a little bit of "delay" meaning, this thing is not used to implement lazy loading.
To put it simply, jQuery._Deferred is a function queue. Its functions are as follows:
Save several functions.
Execute all saved functions at a specific time.
After execution, the new function will be executed immediately.
Does it feel similar to something? Yes, jQuery's ready function has such logic. In fact, the ready function in jQuery 1.5 has indeed been grafted onto it.
jQuery._Deferred provides the following interface:
done: in the form of function(fn1, fn2, ...), used to add functions to the queue.
fire: In the form of function(context, args), use context to specify this object, args to specify parameters, and call all functions in the queue. After fire is called, _Deferred will enter the isResolved state, and future calls to done will not save the function, but call the function directly.
resolve: Equivalent to calling fire(this, arguments), a simplified method.
isResolved: Used to determine whether _Deferred is in the isResolved state. For details, refer to the explanation of the previous fire function.
cancel: Cancel the entire queue, so that no matter whether there is fire or not in the future, the functions in the queue will not be called again.
Now that jQuery._Deferred is explained clearly, let’s take a look at jQuery.Deferred. This thing is actually composed of two _Deferreds. The first is called deferred, which is used to store functions in the "normal" state; the second is called failDeferred, which is used to store functions in the "error" state. At the same time, jQuery.Deferred provides some new interfaces:
then: in the form of function(done, fail), add done to deferred and fail to failedDeferred.
fail: equivalent to the done function of failDeferred.
fireReject: equivalent to the fire function of failDeferred.
reject: Equivalent to the resolve function of failDeferred.
isRejected: Equivalent to the isResolved function of failDeferred.
At the same time, jQuery.Deferred cancels the cancel function.
So what is this used for? There are two states: "normal" and "error", and it is asynchronous at the same time. It is easy to think of... Yes, it is used for AJAX. I will explain it in detail in the next analysis.
Changes in jQuery.ready
Because of jQuery._Deferred, the jQuery.ready function becomes dependent on the function queue. The specific changes are:
The original readyList variable is no longer an array, but becomes a jQuery._Deferred object.
The original logic of calling all functions in readList when DOMContentLoaded is now also used in jQuery._Deferred. The original code:
while ( (fn = ready[ i ]) ) {
fn.call( document, jQuery );
}
becomes:
readyList .fire( document , [ jQuery ] );
jQuery.parseXML function
Added a new static function jQuery.parseXML to provide browser-compatible slave characters The function of converting string into XML document.
There are many logics for this function, and there is nothing special about jQuery. They are roughly divided into the following two types:
For standard browsers, use the DOMParser object:
var parser = new DOMParser();
var xml = parser.parseFromString(text , 'text/html'); For IE, use the Microsoft.XMLDOM object:
var parser = new ActiveXObject('Microsoft.XMLDOM');
parser.async = 'false';
parser.loadXML(text);
var xml = parser.documentElement;
data section
Added the jQuery.hasData function, which is used to determine whether an element has data attached by jQuery.
Modified the implementation of jQuery.expando. In addition to simply taking the current time, a random number was added:
expando = "jQuery" ( jQuery.fn.jquery Math. random() ).replace( /D/g, "" ); This ensures that multiple jQuery copies are introduced at the same time, and the expando between these copies will not conflict with each other, causing the data on the elements to become disordered. Generally speaking, multiple copies of jQuery will not be introduced, but when using SealJS, etc., such problems can easily occur if the configuration is improper.
DOM operation part The original hasClass, addClass, and removeClass functions all need to separate the class attribute of the element into an array. In version 1.4.4, they are separated by n or. Added a new one in 1.5
, used to correspond to the newline character (rn) on the Windows platform.
jQuery.fn.attr function, in version 1.4.4, refuses to obtain attributes from TextNode and CommentNode, and in version 1.5, an AttributeNode (noteType == 2) is added.
In version 1.4.4, jQuery will clean up all DOM events maintained by jQuery when the page is unloaded. This is to avoid the memory leak problem of IE. But this piece of code disappeared in 1.5. I don’t know why.
Regarding the problem of using cloneNode to copy nodes under IE, events will also be copied together. In 1.4.4, the method was solved by copying innerHTML, while in 1.5, the method provided by the mootools team was adopted. Use the cloneFixAttribute function to fix this problem.
The cloneFixAttribute functions are located in lines 5388-5438 of the jQuery 1.5 beta1 source code file. The principle of dealing with IE bugs is very simple. Of course, some seemingly simple things in the front end are difficult to find:
There is a function called clearAttributes in IE, which will clear all attributes on the node. By the way, attributes such as onclick related to the event will also be removed. Calling this function on the copied node will clear the attributes.
There is also a function called mergeAttributes in IE, which copies the attributes of one node to another node, but it will not copy the attributes related to the event. So call mergeAttributes on the original node and put the attributes back on the copied node. This is equivalent to removing event-related attributes.
In addition, the cloneFixAttribute function also handles many compatibility issues of IE6-8 on cloneNode, which is worth studying in detail.
AJAX part
AJAX has been completely rewritten, leaving only a few corners to retain the style of version 1.4.4. Here, only a part is extracted for a brief explanation.
The implementations of $.get and $.post in the original version are very similar. Specifically, only one method configuration item is different, so it was merged in version 1.5:
$.each(['get', 'post'], function(i, method) {
$[method] = function() { ... };
});
The ajaxSetup function now adds a line of return this; and can be called in a chain.
The serializeArray function now uniformly replaces newline characters in value with Windows style (rn).
In the AJAX callback function, the object used as a parameter is no longer the native XMLHTTPRequest, but an object called jXHR encapsulated by jQuery itself. This object provides a common interface for XMLHTTPRequest.
Originally, in addition to 200-299 and 304, there is also a 1223 for the "request successful" browser status code. This comes from a BUG in IE that changes the 204 status code to 1223. Now because of the jXHR object, it is equivalent to an extra layer in the middle, so the statusCode obtained from the jXHR object will not appear as 1223, but has been changed back to 204.
There is an additional statusCode item in the configuration items of jQuery.ajax function. Its structure is map, which is used to specify the callback function when returning a specific status code. The general form is as follows:
jQuery.ajax({
url: 'xxx',
statusCode: {
200: function() {Processing request successfully},
404: function() {Processing page not found},
503: function() {Processing Service Unavailable}
}
}) ;
After adding this callback, the jQuery.ajax function already has a lot of callback functions. The triggering process is as follows:
Trigger the success or error callback based on the returned status code.
Trigger the corresponding statusCode callback based on the status code.
Trigger complete callback.
Trigger global ajaxComplete callback.
If there is no AJAX being executed at this time, trigger the global ajaxStop callback.
Other details
The entry function jQuery.fn.init now has an additional parameter, the value is always rootjQuery, which is used to speed up the search speed of the rootjQuery variable in the init function (reducing a layer of effect Domain):
//jQuery 1.5 beta1 source code line 23
jQuery = function( selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}jQuery object support has been inherited. The specific modification is to change several codes that directly call jQuery into calls to this.constructor:
Line 202: return this.constructor( context ).find( selector );
Line 253: var ret = this.constructor();
Line 334: return this.prevObject || this.constructor(null) ;At the same time, the jQuery.subclass function is also provided to create a type that inherits from jQuery. Since jQuery is not very commonly used, and it has never been used to inherit jQuery, it is not convenient to say how useful this function is.