JQuery selector source code explanation (1): Sizzle method_jquery-js tutorial

Source: Internet
Author: User
This article mainly introduces the jQuery selector source code explanation (1): Sizzle method. This article uses a detailed comment to explain the implementation source code of the Sizzle method, if you need it, you can refer to the following in-depth analysis of jQuery's Sizzle methods (as well as some online materials) and share the results with you. I will use the serialization method to explain in detail some methods used by Sizzle. Each article introduces a method.

If you need to reprint the data, please specify the source. Thank you.

/** The Sizzle method is the main entry to the Sizzle selector package. jQuery's find method is to call this method to obtain matching nodes * This method mainly completes the following tasks: * 1. For a single selector, if it is one of the three types: ID, Tag, and Class, the system directly obtains and returns the result * 2. For browsers that support the querySelectorAll method, run querySelectorAll to obtain and return the matched DOM element * 3. Call the select method to obtain and return the matched DOM element *** @ param selector string * @ param context execute the initial context of the match (that is, the DOM element set ). If the context value is not assigned, the document is used. * @ Param results: the final result of the matched part. If results is not assigned a value, an empty array is assigned. * @ Param seed initial set */function Sizzle (selector, context, results, seed) {var match, elem, m, nodeType, // QSA varsi, groups, old, nid, newContext, newSelector;/** preferredDoc = optional values Doc ument ** setDocument method to complete some initialization work */if (context? Context. ownerDocument | context: preferredDoc )! = Document) {setDocument (context);} context = context | document; results = results | [];/** if selector is not a valid string type data, then results */if (! Selector | typeof selector! = "String") {return results;}/** if context is neither document (nodeType = 9) nor element (nodeType = 1 ), then return the empty Set */if (nodeType = context. nodeType )! = 1 & nodeType! = 9) {return [];} // if the HTML document is currently filtered and seed is not set, run the if (documentIsHTML &&! Seed) {/** if the selector is a single selector and is one of the three types: ID, Tag, and Class, the system directly obtains and returns the result ** rquickExpr =/^ (?: # ([\ W-] +) | (\ w +) | \. ([\ w-] + )) $/* the three paragraphs in the brackets of the above regular expression are used to determine whether the single selector is ID, TAG, and CLASS respectively. * The above regular expression has three subexpressions in the outermost parentheses (namely, three parentheses ), * represents the values of ID, Tag, and Class selector respectively. In the following code, match [1], match [2], match [3] */if (match = rquickExpr.exe c (selector) {// Speed-up: sizzle ("# ID") // process the ID type selector, for example, # IDif (m = match [1]) {// if the current context is a document, then execute the if statement body if (nodeType = 9) {elem = context. getElementById (m); // Check parentNode to catch When Blackberry 4.6 // returns // nodes that are no longer in the document # 6963if (elem & elem. parentNode) {// Handle the case where IE, Opera, and Webkit // return items // by name instead of ID/** some earlier browsers treat name as ID, * return incorrect results, so we need to compare and return the node ID attribute again */if (elem. id = m) {results. push (elem); return results ;}} else {// Context is not a document/** contains (context, elem) To check whether the obtained elem is the sub-object of the current context object */if (context. ownerDocument & (elem = context. ownerDocument. getElementById (m) & contains (context, elem) & elem. id = m) {results. push (elem); return results ;}// Speed-up: Sizzle ("TAG") // process the Tag type selector, for example: SPAN} else if (match [2]) {push. apply (results, context. getElementsByTagName (selector); return results; // Speed-up: Sizzle (". CLASS ")/** process class type selectors, such :. class * the following condition judgments are: * M = match [3]: Valid class type selector * support. getElementsByClassName p of this selector supports getElementsByClassName * context. getElementsByClassName the current context node has the getElementsByClassName method **/} else if (m = match [3]) & support. getElementsByClassName & context. getElementsByClassName) {push. apply (results, context. getElementsByClassName (m); return results ;}// QSA path/** if the browser supports the querySelectorAll method and the selector complies with the querySelectorAll call standard Execute the if statement body * here the check is only a simple match * When Sizzle is called for the first time, rbuggyQSA is blank ** if the body of the statement assigns and restores the id of the current context object, is a BUG used to fix querySelectorAll * this BUG will return the current node (context) as a result in some cases. * The specific method is to add an attribute selector before the existing selector: [id = XXX], * XXX is the id of the context. If the context itself does not set an id, the default value is expando. */If (support. qsa &&(! RbuggyQSA |! RbuggyQSA. test (selector) {nid = old = expando; newContext = context; // If context is document, newSelector is taken from selector, otherwise, falsenewSelector = nodeType = 9 & selector; // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the // root // and working up from there (Thanks to Andrew Dupont // the technique) // IE 8 doesn' t work on object elementsif (nodeType === 1 & context. nodeName. toLowerCase ()! = "Object") {groups = tokenize (selector); if (old = context. getAttribute ("id") {/** rescape =/'| \/g, * Here, a backslash (* old) is added before single quotes, vertical bars, and backslashes in old. $ & in replace (rescape, "\\$ &") code indicates a match */nid = old. replace (rescape, "\\$ &");} else {context. setAttribute ("id", nid) ;}nid = "[id = '" + nid + "']"; // recombine the new selector I = groups. length; while (I --) {groups [I] = nid + toSelector (groups [I]);}/** rsibling = new RegExp (whitesp Ace + "* [++] ") * Rsibling is used to determine whether the selector has a sibling relationship * if it contains ~ The parent node of the context as the current node */newContext = rsibling. test (selector) & context. parentNode | context; newSelector = groups. join (",");} if (newSelector) {/** use try... catch, * because some selectors supported by jquery are not supported by querySelectorAll. * when these selectors are used, querySelectorAll reports an invalid selector. * jquery must implement them. */Try {// merge the results obtained by querySelectorAll into results, and then return resulstspush. apply (results, newContext. querySelectorAll (newSelector); return results;} catch (qsaError) {} finally {if (! Old) {context. removeAttribute ("id") ;}}}// All others // In addition to the preceding shortcut and querySelectorAll method, all others need to call select to obtain the result/** rtrim = new RegExp ("^" + whitespace + "+ | ((?: ^ | [^ \\\\]) (? :\\\\.) *) "* + Whitespace +" + $ "," g "), * whitespace =" [\ x20 \ t \ r \ n \ f] "; * The rtrim regular expression is used to remove the blank spaces on both sides of the selector, blank characters are defined by the whitespace variable * rtrim effect and new RegExp ("^" + whitespace + "+ |" + whitespace + "+ $", "g ") similar to */return select (selector. replace (rtrim, "$1"), context, results, seed );}

Dear friends, if you think it's a good job, help me with it and give me some motivation. Thank you!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.