var Sizzle = function (selector, context, results, Seed) {//context default to document, can be manually specified results = results | | [];context = Context | | Document;var Origcontext = context;//Determine the document node if (context.nodetype!== 1 && context.nodetype!== 9) {return [];} Whether the expression is a string if (!selector | | typeof selector!== "string") {return results;} Set: Seed set//checkset: a copy of the seed set//extra: Save the remaining parallel expressions, note the parallel expression//ret: The result of the initial return, the data type is JSON, contains the set and expr attributes, set is the seed set, and expr is the remaining block expression CUR: block expression relationship such as: + > ~, if not, the default is a space ""//pop: the last variable that pops up the array//parts: stores the currently segmented block expression array var m, set, Checkset, Extra, ret, cur, pop , I,prune = True,contextxml = Sizzle.isxml (context), parts = [],sofar = selector;//Reset The position of the Chunker Reg Exp (start from head)//split fast expression, for the parallel expression encountered, the temporary end, the remaining parallel expression stored in the extra//as #info. p,div.red > ADO {chunker.exec (""); m = Chu Nker.exec (SOFAR); if (m) {Sofar = m[3];p arts.push (m[1]);//According to the above Chunker regular, if there is a parallel expression, then after Exec, m[2] value is "," if (M[2]) {/ /M[3] for the remaining parallel expression extra = m[3];break;}} while (m);//will be cut as follows://parts ["#Info ",". P "], extra:div.red > a//Determine if there is a position pseudo-class origpos, such as: Frist,:last, if there is a location pseudo-class, then take a left-to-right search if (Parts.length > 1 && Amp Origpos.exec (selector)) {if (parts.length = = = 2 && expr.relative[parts[0]]) {set = Posprocess (Parts[0] + p ARTS[1], context, seed);} else {set = expr.relative[parts[0]]? [context]: Sizzle (Parts.shift (), context), while (parts.length) {selector = PA Rts.shift (); if (expr.relative[selector]) {selector + = Parts.shift ();} set = Posprocess (selector, set, Seed);}}} else {//Take a shortcut and set the context if the root selector are an id//(but not if it'll be faster if the inner Sele ctor is an ID)//Here mainly modifies the context, if the expression begins with an ID type, and the last expression is non-ID type//all queries, Use to Sizzle.selector.find, only the last node, the other nodes can use the relationship to determine//Why only the first ID can be modified when the context, and the last one cannot be an ID, Because getElementById only exists in document//does not exist in element, such as the last element is an ID, then an error is immediately//Then the context is modified to the node where the ID is located, to improve efficiency//such as: $ ("#info. P") ; Then the automatic modification is as follows: $ (". P", $ ("#info")), if (!seed && parts.length > 1 && context.NodeType = = = 9 &&!contextxml &&expr.match.id.test (parts[0]) &&! Expr.match.ID.test (Parts[parts.length-1])) {//Call the Find method, query the first element in parts, return the temporary result//as above #info. P then directly query the #info, return the result ret = Sizzle.find (Parts.shift (), context, contextxml);//Then Modify Contextcontext = ret.expr? Sizzle.filter (ret.expr, Ret.set) [0]: ret.set[0];} if (context) {///because it is a right-to-left search, the last element of the array is first fetched, called Parts.pop ();//The Find method is called to query ret = seed? {Expr:parts.pop (), Set:makearr Ay (Seed)}: Sizzle.find (Parts.pop (), parts.length = = = 1 && (parts[0] = = = "~" | | parts[0] = = = "+") && cont Ext.parentnode? Context.parentNode:context, contextxml);//filter the result to set = ret.expr? Sizzle.filter (ret.expr, Ret.set): ret.set;if (Parts.length > 0) {checkset = Makearray (set);} else {prune = false; }//continues to manipulate the left part of the last element in the block expression, if present, call relationship regular judgment//such as 1. div.red > P, then the above has already queried p, then the element in parts now is [' div.red ', ' > '];//2. Div.red p, then the above has already queried p, then now the element in parts is [' div.red '];while (parts.length) {//Remove the last element, that is, ' > ', ifTwo cases, then the direct is ' div.red ' cur = parts.pop ();p op = cur;//If there is a relationship symbol, if it is a space if (! expr.relative[cur]) {//query whether there is a cur type, as in the second case, assign the value "" to cur, then the pop is div.redcur = "";} else {//Remove the previous level element, as in the first case, you need to re-fetch the last element for div.redpop = Parts.pop ();} If the pop is empty, then the default is documentif (pop = = null) {pop = context;} Call relationship regular judgment, pop is the expression of the left element, Checkset for the element to be filtered, cur for the relationship///Here to emphasize is, can someone will find, here is a direct call, there is no return value,//So filtered after the resulting results how to return it? Here is the use of the JavaScript function to pass the array is passed the value of the way, the function of the call to modify the value of Checkset//So in the back to use the value of Checkset, will also change expr.relative[cur] (checkset, pop, contextxml);}} else {checkset = parts = [];}} if (!checkset) {checkset = set;} if (!checkset) {sizzle.error (cur | | selector);} if (Tostring.call (checkset) = = = "[Object Array]") {if (!prune) {results.push.apply (results, checkset);} else if (CO ntext && Context.nodetype = = 1) {for (i = 0; checkset[i]! = NULL; i++) {if (Checkset[i] && (checkset[ I] = = = True | | Checkset[i].nodetype = = = 1 && sizzle.contains (context, checkset[i])) {Results.push (set[i]);}}} else {for (i = 0; CHECKSET[I]! = NULL; i++) {if (checkset[i] && Checkset[i].nodetype = = = 1) {Results.push (set[i]);}}}} else {Makearray (checkset, results);} if (extra) {//There are parallel expressions, recursive calls to sizzle (extra, origcontext, results, Seed),//To the result sort to go heavy, merge sizzle.uniquesort (results);} return results;};
JQuery Sizzle Portal [Source analysis]