jquery Selector code detailed (eight)--addcombinator function

Source: Internet
Author: User

function Addcombinator (Matcher, Combinator, Base)

1. Source Code

function Addcombinator (Matcher, Combinator, base) {var dir = combinator.dir, checknonelements = base&& dir = = = "Pa Rentnode ", Donename = Done++;return combinator.first?//Check against closest ancestor/preceding Elementfunction (Elem, C Ontext, XML) {while ((Elem = Elem[dir]) {if (Elem.nodetype = = = 1 | | checknonelements) {return Matcher (Elem, Context, XML) ;}}} ://Check against All ancestor/preceding elementsfunction (elem, context, XML) {var data, cache, Outercache, Dirkey = Dirru NS + "" + donename;//We can ' t set arbitrary data on XML nodes, so they don ' t//benefit from dir cachingif (XML) {while ( (Elem = Elem[dir])) {if (Elem.nodetype = = = 1 | | checknonelements) {if (Matcher (elem, Context, XML)) {return true;}}} else {while ((Elem = Elem[dir])) {if (Elem.nodetype = = = 1 | | checknonelements) {outercache = Elem[expando] | | (Elem[expando] = {}), if ((cache = Outercache[dir]) && cache[0] = = = Dirkey) {if (data = cache[1]) = = = True| | data = = = Cachedruns) {return data = = = True;}} else {cache = Outercache[dir] = [Dirkey];cache[1] = Matcher (elem, Context, XML) | | cachedruns;if (cache[1] = = = True) {RET Urn true;}}}}};}

2. function

Generates the execution function for the relationship selector.

3. Parameters

Matcher--A continuous filter selector matching function array before the position relationship, which is used to match whether the node obtained through the positional relationship meets the selector requirements. During the actual execution, the function may be a elementmatcher (matchers) that has been generated before the relationship selector. For example: Div.map>span, when the sizzle compilation encounters >, the Div.map compiler function is called as the first parameter Addcombinator function to check whether the captured span sibling node satisfies the div.map condition.

Combinator-The relationship selector corresponds to the value in the expr.relative, and the values of the various relationship selectors in expr.relative are as follows. Use the first property of this parameter to determine whether the function that is returned is to check only the functions that are immediately adjacent to the object or to traverse all possible objects. The node with the specified position relationship will be obtained by using the following code: Elem = Elem[dir], where dir equals combinator.dir.

Expr.relative: {">": {dir: "ParentNode", first:true}, "": {dir: "ParentNode"}, "+": {dir: "previoussibling", firs T:true}, "~": {dir: "PreviousSibling"}}

Base--This parameter, together with Combinator.dir, determines the value of the variable checknonelement, as shown in the code below. This value is literally interpreted as a non-dom element that is currently checked, that is, when elem.nodetype!=1, if the value is true, the matching function is executed, or the loop is ended.

4. Return function

4.1 If the relationship selector is > or +, the following function is returned:

function (elem, context, XML) {while ((Elem = Elem[dir])) {if (Elem.nodetype = = = 1 | | checknonelements) {return Matcher (ele m, context, XML);}}}
4.1.1 function

If you check the element type node (that is, checknonelements==false), the iteration gets the first element type node (Elem.nodetype = = 1) elem The specified position relationship, executes the matching function, checks whether the node meets the requirements, Returns False if True is returned;

If you check all types of nodes (that is, checknonelements==true), get the adjacent node elem the specified location relationship, execute the matching function, check whether the node meets the requirements, or return False if True is returned;

Some people may ask, not to say, close relationship? Why is there an iterative acquisition of this process in the code? This is because individual browsers think of line breaks between node text as Textnode, so during processing, these nodes need to be skipped until the next element node.

4.1.2 Parameters

elem--the individual node element to be inspected.

context--executes a context node that matches the entire selector string, and most of the time it has no purpose.

xml--whether the current search object is HTML or an XML document, and if HTML, the XML parameter is false.

4.2 If the relationship selector is a ~ or a space, the following function is returned:

Check Against all ancestor/preceding elementsfunction (elem, context, XML) {var data, cache, Outercache, Dirkey = Dirruns + "" + donename;//We can ' t set arbitrary data on the XML nodes, so they don ' t//benefit from dir cachingif (XML) {while (E Lem = Elem[dir]) {if (Elem.nodetype = = = 1 | | checknonelements) {if (Matcher (elem, Context, XML)) {return true;}}} else {while ((Elem = Elem[dir])) {if (Elem.nodetype = = = 1 | | checknonelements) {outercache = Elem[expando] | | (Elem[expando] = {}), if ((cache = Outercache[dir]) && cache[0] = = = Dirkey) {if (data = cache[1]) = = = True| | data = = = Cachedruns) {return data = = = True;}} else {cache = Outercache[dir] = [Dirkey];cache[1] = Matcher (elem, Context, XML) | | cachedruns;if (cache[1] = = = True) {RET Urn true;}}}};

4.2.1 function

If you are checking an XML document, the procedure is consistent with the 4.1 return function, as shown in the code above if (XML) {...} The code inside the curly braces.

If the HTML document,

4.2.2 Parameters

elem--the individual node element to be inspected.

context--executes a context node that matches the entire selector string, and most of the time it has no purpose.

xml--whether the current search object is HTML or an XML document, and if HTML, the XML parameter is false.

4.2.3 Code Description

Internal variables

dirkey--the key used by the cache node detection result. During a single execution, if a node is checked, the detection result (true or false) is recorded in the node's Dirkey property (the value of the property name is Dirkey), and it is not necessary to detect the node again when it is encountered during this execution. Caching is required because multiple nodes have the same parent or sibling node, and using caching can reduce the number of detections and improve performance.

dirruns--each execution of precompiled code through the Matcherfromgroupmatchers organization produces a pseudo-random number that distinguishes the different execution processes.

donename--each time the Addcombinator function is executed, the done variable adds 1 to distinguish between the different positional relationship matching functions that are generated.

cachedruns--is used to record the number of DOM elements in this match. For example: Div.map>span, with 3 elements conforming to the span selector, when the > match function is executed for each element, Cachedruns is 0, 1, 2 in turn. The role of Cachedruns can be directly understood as code in the process of one execution, for the same element using elementmatchers for the matching process, once again encountered the same element, you can directly from get the result of the mismatch, but I do not think that the situation will happen this kind of thing. If someone encounters, please inform, thank you!

Code explanation

while ((Elem = Elem[dir])) {if (Elem.nodetype = = = 1 | | checknonelements) {///If the Elem attribute of the expando node does not exist, an empty object is given, and the outercache/ /If the expando attribute of the Elem node exists, assign its value to Outercacheoutercache = Elem[expando] | | (Elem[expando] = {}),/* * If OUTCACHE[DIR] has a value, and its first element equals the current Dirkey, * indicates that the current position selector has detected the node during this execution, executes the statement within if, and obtains the result directly from the cache * if out Cache[dir] does not exist, or the first element is not equal to the current Dirkey, * indicates that the current position selector has not detected the node during this execution, executes the statement inside the else, matches the node and puts the result in the cache */if ((cache = Outercache[dir ]) && cache[0] = = = Dirkey) {//If the test result in the cache equals True or Cachedruns value, then the detection result (not true is false) is returned,// Otherwise, continue the loop to get the last node that matches the location relationship if (data = cache[1]) = = = True| | data = = = Cachedruns) {return data = = = True;}} else {//assigns the array [Dirkey] to outercache[dir] and Cachecache = outercache[dir] = [Dirkey];//will match successfully, giving true to cache[1], otherwise cachedruns Value given to cache[1]cache[1] = Matcher (elem, Context, XML) | | cachedruns;//returns True if the match result is true, otherwise the loop gets the last node that matches the position relationship to match if (cache[1] = = True) {return true;}}}

<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43760275" >jquery selector code detailed (a)-- Sizzle Methods </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43762435" >jquery selector code in detail (ii)-- Select Method </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43770075" >jquery selector code in detail (iii)-- Tokenize Methods </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43797213" >jquery selector code in detail (iv)-- Expr.prefilter</a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43800947" >jquery selector code in detail (v)-- An example illustrates the parsing process of tokenize </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43935009" >jquery selector code detailed (vi)-- Sizzle Selector matching logic analysis </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43955597" >jquery selector code detailed (vii)-- Elementmatcher functions </a></p>
<p><a target= "_blank" href= "http://blog.csdn.net/mole/article/details/43955841" >jquery selector code detailed (eight)-- Addcombinator functions </a></p>



jquery Selector code detailed (eight)--addcombinator function

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.