I recently read some analysis articles about Sizzle on the Internet. As for the matching order, it is often said that the reverse matching method from right to left is used, but the specific details are not introduced in detail, or just like my previous articles, The code is introduced in detail line by line, but the overall concept is lacking. Here is an overall explanation of the matching logic (precompiled results) of jQuery-1.10.2 version of Sizzle. I will not go into too many details here.
Sizzle’s matching process uses an improved version based on the reverse matching method from right to left. After all, HTML search is different from text matching. It has its own unique side. Therefore, HTML search is required. Optimize. Let me make it clear first that the relationship selector mentioned below refers to the Combinator selector in W3C. Because I feel that the name relationship selector is closer to the actual meaning than others, so I named it this way.
1. Briefly introduce the two main functions compiled and executed by Sizzle:
a) matcherFromTokens - Generate an execution function for a block selector. The so-called block selector is a selector string that does not contain comma separation.
b) matcherFromGroupMatchers - the final execution function that generates different block selectors. This function is also responsible for filtering out duplicate objects from the final results.
2. The matcherFromTokens function generates different execution functions for different types of selectors. If it contains a pseudo-class, setMatcher is returned, otherwise elementMatcher is returned. The code distinguishes setMatcher and elementMatcher by identifying whether the matcher contains the expando attribute:
a) For non-pseudo-class and non-relational selectors, execution functions are generated directly from left to right, and each function exists as a different element of the same matchers array.
b) For the relationship selector, the previously generated matchers will be pushed into a new matchers array.
c) For the pseudo-class selector, an execution function will be generated through the setMatcher function. When calling setMatcher, six parameters will be passed in, namely preFilter, selector, matcher, postFilter, postFinder, and postSelector.
PreFilter is the final function processed by the elementMatcher function on the matchers array generated before executing the setMatcher function. elementMatcher(matchers) will return a new function that executes each matchers element function from back to front;.
selector is the selector string corresponding to matchers;
matcher is the matching function of the pseudo class itself;
PostFilter is the matching function corresponding to the selector string between the pseudo-class and the first pseudo-class or relationship symbol. It is the return result of nested calling matcherFromTokens function;
PostFinder is the matching function generated by all selectors after the postFilter corresponding selector. It is also the return result of nested calling matcherFromTokens function;
PostSelector is the selector string corresponding to postFinder.
d) If there is no pseudo-class in the selector string, then the final matching function generated by elementMatcher(matchers) will be returned.
As can be seen from the above introduction, there is a nested relationship between the generated execution functions. Simply put, setMatcher contains matchers, and the relational selector matching function contains non-pseudo-class and non-relational selector matching functions.
3. Introduction to the execution process:
a) Execution function of the execution block selector:
For elementMatcher, it is executed in sequence from outside to inside and from back to front, that is, from the outermost array to the innermost array. In the same array, it is executed in sequence from the last element to the first element.
For setMatcher, first obtain the matching result based on preFilter and selector; then execute the matcher function to obtain the matching result; then, execute the postFilter function, and finally, obtain the matching result based on postFinder and postSelector.
c) After executing the execution function of each block selector in sequence, filter out duplicate data and return the result.
After reading the above general process, it should be easier to understand when looking at the detailed introduction of each method. Of course, some details are not discussed here, such as the generation of the initial result set (seed) and the resulting function execution logic details. Differences etc.