1-1 jquery design Concept
Introduction to Wikipedia:
jquery is another excellent JavaScript framework following prototype. It is a lightweight JS library, it is compatible with CSS3, also compatible with various browsers (IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+), jQuery2.0 and subsequent versions will no longer support Ie6/7/8 browser. jquery makes it easier for users to work with HTML (an application under the standard Universal Markup Language), events, animate, and easily provide Ajax interactivity to the site. One of the big advantages of jquery is that its documentation is full, and the various applications are very detailed, as well as a number of mature plugins to choose from. jquery allows the user's HTML page to keep the code and HTML content separate, that is, no longer inserting a bunch of JS in the HTML to invoke the command, just define the ID.
The Write Less,do more (write less, do more), is undoubtedly the core concept of jquery, concise API, elegant chain, powerful query and convenient operation. Thus the jquery into the front-end world of a sword, invincible!
Concise API:
$.on$.css$.ajax ....
Elegant chain style:
var jqxhr = $.ajax ("example.php") . Done (function () {alert ("Success");}) . Fail (function () {alert ("error");}) . Always (function () {alert (' Complete ');});
Powerful selector:
$ ("Div, span, p.myclass") $ ("div span:first-child") $ ("tr:visible") ...
Easy to operate:
$ ("P"). Removeclass ("MyClass noclass"). AddClass ("YourClass"); $ ("ul Li:last"). AddClass (function (index) { return "item-" + Index;}); $ ('. Container '). Append ($ (' H2 '));
Why do you want to do jquery source parsing?
While the documentation for jquery is perfect, subconsciously lowers the threshold for front-end development, to implement an animation handy, as long as a simple call to a animate method to pass a few execution parameters can be, but if we want to implement a custom animation it? There are too many issues to consider, such as browser compatibility, acquisition of various attributes, logic flow, performance, and so on, which are the core of the front-end development.
If we only know the use of jquery, and do not know its principle, that is "know it, and do not know the reason why", said so much, then quickly follow the MU class network into the "Tall" journey, in-depth to explore the internal structure of jquery!
1-2 jquery Overall Architecture
Any program code is not complex at first, success is not a energetically, and early jquery author John Resig in 2005 proposed to improve prototype's "behaviour" library, just want to make it easier to publish a new jquery framework. At first John Resig did not anticipate that jquery would be so hot. We can see from the beginning of the release of the first 1.0 to the latest 2.1.1 its code expanded to more than 9,000 lines, it is compatible with CSS3, but also compatible with a variety of browsers, jquery makes it easier for users to handle the DOM, events, animations, and convenient for the site to provide Ajax interaction.
1, the latest jQuery2.1.1 version of the structure:
Code See right-Hand Code editor (1-24 lines)
2, jquery's module dependency network:
(Click the picture to enlarge)
jquery is a total of 13 modules, starting with the 2.1 version of jquery support through the AMD Module division, jquery in the first release of the 1.0 version is very simple, only CSS selectors, event processing and Ajax interaction 3 chunks. There have been several important changes in the course of its development:
? 1.2.3 release, introduce data cache, solve the problem of circular reference and big data saving ? Release 1.3, it uses a new selector engine sizzle, in each browser to completely surpass the other similar JavaScript framework query speed, library performance has been greatly improved ? Version 1.5 released, new delay to the image (Deferred Objects), and Deferred rewrite the Ajax module ? Release 1.7, which abstracts out callback objects, provides a powerful way to manage the list of callback functions.
Each big improvement has introduced some new mechanism, the new characteristic, through these new mechanism created today jquery library, altogether 13 modules, the module is not single, for example jquery animation, will rely on the asynchronous queue, the animation queue, the callback queue and the data cache module and so on.
jquery pulls out all the reusable features, separating out a single module, and using a combination of methods, jquery is very clever in both design and implementation.
Five chunks:
jquery is divided into five chunks, selectors, dom operations, events, Ajax and animations, so why are there 13 modules? Because the design of jquery is one of the most favorite things to do, is to pull together the characteristics of the "modular", of course, is closer to s.o.l.i.d Five principles of "single responsibility SRP", the advantage of following a single duty is that we can easily maintain this object, for example, When an object encapsulates a lot of responsibilities, once a duty needs to be modified, it will inevitably affect the other responsibility code of the object. Decoupling allows each responsibility to change more flexibly.
Let's take a look at the jquery document provides a series of façade interfaces for the processing of the business layer's Ajax:
. Ajaxcomplete (). Ajaxerror (). Ajaxsend (). Ajaxstart (). Ajaxstop (). Ajaxsuccess ()
Bottom-Level interface:
Jquery.ajax () Jquery.ajaxsetup ()
Quick Method:
Jquery.get () Jquery.getjson () Jquery.getscript () Jquery.post ()
Design principle of jquery interface
Business logic is complex, and jquery has a lot of high-level APIs, and it's also very detailed, which makes it easier for developers to operate without having to overload too many actions on one interface. We are looking inside the Ajax high-level method is actually unified call a static Jquery.ajax method, code see the Right Code Editor (27-43 lines).
The internal implementation of Jquery.ajax is very complex, first of all, Ajax to consider asynchronous processing and callback unity, so the introduction of the asynchronous Queue module (Deferred) and callback module (callbacks), so the method of these modules in the Ajax method inside again encapsulated, Constructs a new JQXHR object, for the default processing of parameters, data transmission format and so on.
1-3 calling an expression immediately
The first point of any library and frame design is to solve the problem of namespace and variable pollution. jquery is the use of JavaScript function scope of the characteristics of the immediate invocation of an expression wrapped in its own way to solve the problem.
The immediate invocation function expression of jquery is written in three ways:
Notation 1:
(Function (window, factory) { Factory (window)} (this, function () { return function () { //jquery call }}) )
It can be seen that the above code is nested in 2 functions, and passing a function as a parameter to another function and execution, this method is a bit complicated, we simplify the wording:
Notation 2:
var factory = function () { return function () { ///Execute method }}var jQuery = Factory ();
The code effect above is equivalent to Method 1, but this factory is a bit of a simple factory method pattern that needs to be called by itself, not like a single jquery class, so we need to change to "self-executing" instead of calling it separately.
Notation 3:
(Function (window, undefined) { var jQuery = function () {} //... ) Window.jquery = window.$ = JQuery;}) (window);
As you can see from the code above, this function is initialized automatically, so that it is built only once. Give me a detailed look at the advantages of this notation:
1, window and undefined are to reduce the scope scope of variable lookup. When the window is passed to the inside of the closure, it can be used as a local variable when using it inside the closure, which is obviously faster than the original search under Window scope.
2, undefined is the same truth, in fact, this undefined is not a JavaScript data type undefined, but an ordinary variable name. Just because the value is not passed to it, its value is that undefined,undefined is not a reserved word for JavaScript.
Have children's shoes message to, why to pass undefined?
Undefined in Javascript is not a keyword, so you can allow users to assign a value to it.
Let's look at a
var undefined = ' mu class net ';(function (window) { alert (undefined);//ie8 ' mu Net '}) (window)
IE8 There is this problem, of course, most browsers are not modifiable
If the function call is not passed, the parameter defaults to undefined
;(function (window,undefined) { //undefined}) (window)
Why does jquery create such an outer package, and how does it work?
Here to distinguish 2 concepts one is an anonymous function, and the other is self-executing. As the name implies, an anonymous function is a function without a function name, that is, there is no external reference. But is it implemented as follows:
function () {//code logic}
The above is wrong, declares it but does not give the name and no use, so syntactically wrong, then how to execute an anonymous function?
To invoke a function, we must have a way to locate it and reference it. So, we're going to take a name:
var jQuery = function () {//code logic}
jquery uses () to enclose the anonymous function, followed by a pair of parentheses (including the argument list), then the parentheses can combine our expressions and each block (that is, each pair of parentheses) has a return value. This return value is actually the return value of the expression in parentheses. So, when we enclose the anonymous function with a pair of parentheses, the actual parentheses return is the function object of the anonymous functions. Therefore, the parenthesis pair plus the anonymous function is like the name of the function that we get its reference position. So if you add a parameter list after the reference variable, the invocation form of the normal function is implemented.
Finally, we go back to writing 1 to see how jquery uses the notation of 3, and then pass the entire function as a parameter to another function, mainly to determine the load logic of jquery under different platforms, and mainstream libraries generally have support codes for AMD and CommonJS. Look at the code for jquery:
if (typeof module = = = "Object" && typeof module.exports = = = "Object") { module.exports = global.document?
factory (Global, true): function (w) { if (!w.document) { throw new Error ("jQuery requires a window with a doc Ument "); } Return Factory (w); };} else { factory (global);}
Summary: The global variable is the devil, the anonymous function can be effectively guaranteed to write JavaScript on the page, without causing the global variable pollution, through the parentheses, let it be loaded immediately initialized, so that a singleton pattern of the effect so that it will only be executed once.
1-4 jquery's class Array object structure
Why are class array objects?
Many confusing jquery can be manipulated like an array, and can be turned into DOM objects by means of an object get method or directly indexed by subscript 0.
First we look at the entry of jquery is a unified $, by passing parameters of different, implemented 9 methods of overloading:
1. JQuery ([Selector,[context]]) 2. JQuery (Element) 3. JQuery (Elementarray) 4. JQuery (object) 5. jquery (jquery object) 6. JQuery (Html,[ownerdocument]) 7. JQuery (Html,[attributes]) 8. JQuery () 9. JQuery (callback)
9 uses can be divided into three chunks: selectors, dom processing, Dom loading.
In other words, jquery exists to get the DOM and manipulate the DOM! So in order to make it easier for these operations, so that the node and the instance object through a bridge to associate, jquery inside a kind of called "Class array Object" as a storage structure, so we can be like an object to handle jquery operations, as well as arrays can use push, pop, The methods of shift, unshift, sort, each, map, and so on, manipulate the jquery object.
What is the principle of using an array subscript index for jquery objects?
$(".Class")
the structure of the object is constructed as follows:
The whole structure is very clear, through the relationship between the object key value of the preservation of properties, the prototype preservation method. Let's simply simulate a data structure like this: (See the right-hand code editor)
The above is the object structure simulating jquery, the concrete process of object creation is abstracted through the Aquery method, which is also a well-known design pattern-factory method in the field of software engineering.
The principle of no new construction of jquery
The function aquery () is first guaranteed to be built with the new operator. This will ensure that the current build is an instance object with this, since it is an object we can put all the properties and methods as the object's key and value of the way to map to this, so as the above structure can simulate the jquery operation, can be indexed by the value, Can also be chained method value, but such a structure is a big flaw, each call ajquery method and so on to create a new instance, then like get method to be recreated on each instance, performance is greatly compromised, so the structure of jquery optimization is not just what we see , in addition to implementing the class array structure, the method of prototype sharing, but also to implement the static and instance of the method coexistence, this is what we will focus on analysis.
1-5 the ready and load events in jquery
jquery has 3 ways to load documents
$ (document). Ready (function () { //... Code ...}) Document ready Shorthand $ (function () { //... Code ...}) $ (document). Load (function () { //... Code ...})
One is the ready one is load, what is the difference between these two?
Ready and load who performed first:
In the course of the interview, you will often be asked a question: ready and load the first execution, that one after execution? The answer is ready to execute before load.
Steps for DOM document loading:
To understand why ready is executed first, the load post-execution needs to understand the next steps of DOM document loading:
(1) parsing the HTML structure. (2) Loading external scripts and style sheet files. (3) Parse and execute script code. (4) Constructs an HTML DOM model. Ready (5) Loads external files such as pictures. (6) The page has finished loading. Load
As you can see from the above description, ready is executed after step (4), but load is not executed until step (6) is complete.
Conclusion:
The difference between ready and load is that the resource file is loaded, ready constructs the basic DOM structure, so the faster the code should load the better. In an era of high-speed browsing, no one is willing to wait for answers. If a site page load more than 4 seconds, I'm sorry, you 1/4 users will face the loss, so for the framework of the user experience is crucial, we should deal with the DOM the better, we do not have to wait until the image resources are loaded before processing the frame loading, Too many picture resources the load event will not be triggered.
Let's look at how jquery handles the timing of document loading:
JQuery.ready.promise = function (obj) { if (!readylist) { readylist = jquery.deferred (); if (document.readystate = = = "complete") { //Handle It asynchronously-allow scripts the opportunity-delay read Y setTimeout (jquery.ready); } else { document.addeventlistener ("domcontentloaded", completed, false); C7/>window.addeventlistener ("Load", completed, false); } } return readylist.promise (obj);};
jquery's ready is packaged through promise, which is the way jquery excels, unifying the callback system, which we'll focus on later.
The specific strategy for jquery compatibility is visible: for advanced browsers, we are happy to use the Domcontentloaded event at the moment, saving time and effort.
So how does the old IE deal with it?
Keep looking at the jquery scenario:
//ensure firing before onload, maybe late but safe also for iframesdocument.attachevent ("Onreadystatec Hange ", completed);//A fallback to window.onload, that would always workwindow.attachevent (" onload ", completed);/If I E and not a frame//continually check to see if the document is Readyvar top = false;try {top = Window.frameelement = = Null && document.documentelement;} catch (E) {}if (top && top.doscroll) {(function Doscrollcheck () {if (!jquery.isready) { try {//Use the trick by Diego Perini//http://javascript.nwbox.com/IEContentLoaded/ Top.doscroll ("left"); } catch (e) {return setTimeout (Doscrollcheck, 50); }//Detach all DOM ready events detach (); and execute any waiting functions jquery.ready (); } })();}
If the browser has document.onreadystatechange
an event, it document.readyState=complete
can be considered as if the DOM tree has been loaded when the event is triggered. However, this event is unreliable, such as when there is a picture on the page, it may be triggered after the OnLoad event, in other words, it can only be performed correctly when the page does not contain binary resources or is very small or cached as an alternative.
Load detection for IE
Diego Perini in 2007, reported a way to detect whether IE is loaded, using DoScroll method invocation, details are visible http://javascript.nwbox.com/IEContentLoaded/.
The principle is that for IE in non-IFRAME, only continuously through can execute doscroll to determine whether the DOM is loaded. In the above interval of 50 milliseconds to try to execute doscroll, note that because the page does not load complete, call DoScroll will cause an exception, so use Try-catch to catch the exception.
Conclusion: So in general, when the page DOM is not loaded, an exception is generated when the DoScroll method is called. Then we use the reverse, if not abnormal, then the page Dom loading is complete.
This is the first time we are dealing with the ready loading problem, if ready is loaded after the page has finished loading?
jquery has to skip binding for such situations:
if (document.readystate = = = "complete") { //Handle It asynchronously-allow scripts the opportunity-delay read Y setTimeout (jquery.ready);}
Determine whether the page has been loaded directly by looking at the status of the readystate. This will give a timer a minimum time to execute after, the main guarantee to execute the correct.
1-6 jquery multi-Library coexistence processing
Docu coexistence in other words can be called conflict-free handling.
In general, there are 2 things you will encounter:
1, $ Too hot, jquery uses $ as a namespace, inevitably conflict with other library frameworks or plugins.
2, jquery version update too fast, plug-ins can not keep up, resulting in different versions of the plug-in support is not the same.
For the above reasons, jquery gives a solution ––noconflict function.
Introducing jquery to run this noconflict function gives control of the variable $ to the first library that implements it, ensuring that jquery does not conflict with the other library's $ objects.
After you run this function, you can only access jquery objects using jquery variables. For example, in places where you would use $ ("Aaron"), you would have to change to jquery ("Aaron"), because the control of $ has been left out.
Use Demo:
Jquery.noconflict ();//Use Jqueryjquery ("Aaron"). Show ();//Use a $ () $ ("Aaron") for other libraries. Style.display = ' block ';
This function must be used after you import the jquery file and before importing another library that causes the conflict. Of course it should be before other conflicting libraries are used, unless jquery is the last one to import.
Because it is relatively simple, we have a direct code commentary:
Var _jquery = window.jquery, _$ = window.$;jquery.noconflict = function (deep) { if (window.$ = = = JQuery) {
window.$ = _$; } if (deep && window.jquery = = = JQuery) { window.jquery = _jquery; } return jQuery;};
If we need to use both jquery and other JavaScript libraries, we can use $.noconflict () to give control of the $ to other libraries. The old reference $ is saved in the initialization of jquery; Noconflict () simply restores them.
Through the concept of swap-like swap, first put the previous namespace to cache, by comparing the current namespace to achieve the purpose of the exchange, first, we first determine whether the current $ space is not taken over by jquery, if it is to give control to the previous _$ referenced library, If the incoming deep is true, then the control of jquery is also allowed out.
If not through the noconflict treatment, its consequences can be imagined, delicious $ everyone "coveted for a long time."
jquery source parsing (architecture and Dependency module) Chapter I Understanding Architecture