Overall architecture
First we look at what happens at home in jquery, the outermost structure of jquery's source code is:
(function(Global, factory) {if(typeofmodule = = = "Object" &&typeofModule.exports = = = "Object" ) { ... } Else{Factory (global); }}(typeofWindow!== "undefined"? window: This,function(window, noglobal) {varJQuery; varstrundefined =typeofundefined; ... if(typeofNoglobal = = =strundefined) {Window.jquery= window.$ =JQuery; }}));
Constructing a JQuery Object
Next look at how the factory method creates the jquery object's
function(window, Noglobal) {...varJQuery =function(Selector, context) {return NewJQuery.fn.init (selector, context); }; Jquery.fn= Jquery.prototype = { ...... }; Jquery.extend= JQuery.fn.extend =function() { ...... }; ...... varinit = JQuery.fn.init =function(Selector, context) {}; Init.prototype=Jquery.fn; ...... if(typeofNoglobal = = =strundefined) {Window.jquery= window.$ =JQuery; } returnjQuery;}
Let's look at how the jquery constructor for the window object creates a jquery instance
varrquickexpr =/^ (?: \ s* (<[\w\W]+>) [^>]*|# ([\w-]*)) $/;Init= JQuery.fn.init =function(Selector, context) {varmatch, Elem; if( !selector) { return This; } if(typeofselector = = = "string" ) { if(Selector[0] = = = "<" && selector[selector.length-1] = = = ">" && selector.length >= 3 ) {Match = [NULL, selector,NULL ]; } Else{Match=rquickexpr.exec (selector); } if(Match && (match[1 | | |!)context)) { if(match[1]) {context= ContextinstanceofJquery? Context[0]: Context;Jquery.merge ( This, jquery.parsehtml (match[1], Context&& Context.nodetype? context.ownerdocument | |Context:document,true ) ); if(Rsingletag.test (match[1]) &&Jquery.isplainobject (context)) { for(Matchinchcontext) { if(Jquery.isfunction ( This[match])) { This[Match] (context[match]);}Else { This. attr (match, context[match]); } } } return This;}Else{Elem= document.getElementById (match[2] ); if(Elem &&elem.parentnode) { This. length = 1; This[0] =Elem; } This. Context =document; This. selector =selector; return This; }}Else if(!context | |context.jquery) {return(Context | |rootjquery). Find (selector);}Else { return This. Constructor (context). Find (selector); }}Else if(selector.nodetype) { This. Context = This[0] =selector; This. length = 1; return This;}Else if(Jquery.isfunction (selector)) {return typeofRootjquery.ready!== "undefined"?Rootjquery.ready (selector):selector (jQuery); } if(Selector.selector!==undefined) { This. selector =Selector.selector; This. Context =Selector.context; } returnJquery.makearray (Selector, This );}
varRsingletag = (/^< (\w+) \s*\/?> (?: <\/\1>|) $/); jquery.parsehtml=function(data, context, keepscripts) {if(!data | |typeofData!== "string" ) { return NULL; } if(typeofContext = = = "Boolean") {keepscripts=context; Context=false; } Context= Context | |document; varparsed =rsingletag.exec (data), scripts=!keepscripts && []; if(parsed) {return[Context.createelement (parsed[1] ) ]; } parsed=jquery.buildfragment ([data], context, scripts); if(Scripts &&scripts.length) {jQuery (scripts). Remove (); } returnJquery.merge ([], parsed.childnodes);};
varRxhtmltag =/< (?! Area|br|col|embed|hr|img|input|link|meta|param) (([\w:]+) [^>]*] \/>/gi;varrhtml =/<|&#?\w+;/;varRtagname =/< ([\w:]+)/;varRscripttype =/^$|\/(?: JAVA|ECMA) script/i;varWrapmap ={option: [1, "<select multiple= ' multiple ' >", "</select>"], thead: [1, "<table>", "</table>"], col: [2, "<table><colgroup>", "</colgroup></table>"], tr: [2, "<table><tbody>", "</tbody></table>"], TD: [3, "<table><tbody><tr>", "</tr></tbody></table>"], _default: [0, "", "" "]};buildfragment:function(elems, context, scripts, selection) {varElem, TMP, tag, wrap, contains, J, fragment=context.createdocumentfragment (), Nodes=[], I= 0, L=elems.length; for(; i < L; i++) {Elem=elems[i]; if(Elem | | elem = = 0 ) { if(Jquery.type (elem) = = = "Object") {Jquery.merge (nodes, Elem.nodetype?[Elem]: Elem); } Else if( !rhtml.test (Elem)) {Nodes.push (Context.createtextnode (elem)); } Else{tmp= TMP | | Fragment.appendchild (Context.createelement ("div") ); Tag= (rtagname.exec (elem) | | [ "", "" ] ) [1].tolowercase (); Wrap= wrapmap[Tag] | |Wrapmap._default; Tmp.innerhtml= wrap[1] + elem.replace (rxhtmltag, "<$1></$2>") + wrap[2 ]; J= wrap[0 ]; while(j--) {tmp=Tmp.lastchild; } jquery.merge (nodes, tmp.childnodes); TMP=Fragment.firstchild; Tmp.textcontent= ""; } }} fragment.textcontent= ""; I= 0; while(Elem = nodes[i++ ]) ) { if(Selection && Jquery.inarray (Elem, selection)!==-1 ) { Continue; } contains=jquery.contains (elem.ownerdocument, elem); TMP= GetAll (Fragment.appendchild (elem), "script" ); if(contains) {setglobaleval (TMP); } if(Scripts) {J= 0; while((Elem = tmp[J + + ]) ) { if(Rscripttype.test (Elem.type | | "") {Scripts.push (elem); } } } } returnfragment;}
(function(window) {varsetdocument, Docelem, Preferreddoc=window.document, Rnative=/^[^{]+\{\s*\[native \w/; functionSizzle (Selector, context, results, Seed) {...} Setdocument= Sizzle.setdocument =function(node) {varHascompare, Doc= node? node.ownerdocument | |Node:preferreddoc; Hascompare=rnative.test (docelem.comparedocumentposition); Contains= Hascompare | | Rnative.test (docelem.contains)?function(A, b) {varAdown = A.nodetype = = = 9?a.documentelement:a, Bup= b &&B.parentnode; returnA = = = Bup | | !! (bup && Bup.nodetype = = = 1 &&(Adown.contains?Adown.contains (BUP): A.comparedocumentposition&& a.comparedocumentposition (BUP) & 16 )); } : function(A, b) {if(b) { while((b =B.parentnode)) {if(b = = =a) {return true; } } } return false; }; } setdocument (); ......}) (window)
The overall architecture and initialization function of jquery technology Insider