Sizzle engine-Principles and Practices (1)

Source: Internet
Author: User

As we all know, sizzle is jquery's royal selector engine and the DOM selector engine written by John resig, the author of jquery. The speed is claimed to be the highest in the industry. In addition, sizzle is an independent part and does not rely on any library. If you do not want to use jquery, you can use only sizzle. So take it out separately. In prototype1.7, the selector also uses sizzle, but the version is a little old, so I went to the sizzle website to create a new version, so the latest version of sizzle is used in the analysis below. JS

Instructions in advance

In the initial stage of analysis, in order to ensure the consistency of the results of various browsers, ignore the influence of native getelementsbyclass and queryselectorall, and ignore the XML type:
Source code 1292 lines,

(function(){
...
})()

Changed:

(function(){
return false;
...
})()

Source code 1140 lines

if ( document.querySelectorAll ) {
...
}

Changed:

if ( document.querySelectorAll && false) {
...
}

Other browser compatibility processing components will be included in the preliminary analysis.

Prerequisites

CSS selector and jquery selector. Because the jquery selector is in the form of CSS, many new selection expressions are added on the basis of CSS. Therefore, everything is based on the jquery selector.

Instance question:

For a selection expression:

div#outer > ul , div p:nth(1),form input[type="text"]
Discussion about chunks

Here, there are three parallel delimiters. What should we do?
Solution:
1. Split (',') can be used for processing, but this is just a simple split, and no more information can be obtained.
2. Therefore, we use regular expressions to block data. The disadvantage is readability and efficiency. The advantage is that we can extract necessary information for preprocessing.

Therefore, jquery adopts regular expressions, but not fully segmented, but partial operations. For the above example, let's look at how to partition.

Div # outer> ul, div P: Nth (1), form input [type = "text"] First separated Div # outer> ul, after processing, div P: Nth (1) is separated. After processing, form input [type = "text"] is separated, and the results of the three parts are merged.

About the sequence of Selection

Remember the role of the jquery selector.

A typical example:

body div p:first-child
body div p:first

The meanings of the two parameters are completely different. If you can use parentheses to write the statements, you can change them:

body div p:first-child --> body div (p:first-child)
body div p:first --> (body div p):first

First-child is used to limit P. It can be regarded as an attribute of P,
Body Div P: First is used to limit the result set of body Div P. It can be regarded as a method of the result set of body Div p.
Body Div P: First = (body Div P). eq (0)

In this case, there are several location Query expressions customized by jquery.
Case 1: Body Div P: first

Query from left to right. First, find the body, obtain set a, then search for div in set a to obtain Set B, search for P in Set B to obtain set C, and finally obtain the first element of set C, the final result is XX.

Case 2: Body Div P: First-child

For a query from the right to the left, locate P: First-child to obtain the set A1, and then determine whether there is a DIV in the ancestor element to obtain the set B1, then, determine whether there is a body in the ancestor element to obtain the C1 set and obtain the final result C1.

Compared with process 1, process 2 is more like a filtering process. Therefore, the biggest highlight of sizzle is the filtering from right to left.

In addition, to improve query efficiency, the most important thing is to narrow the search range and reduce the number of traversal times.
A typical example is:
Div P
Scenario 1: first locate P, obtain set a, and then determine whether there is a DIV in the ancestor element to obtain Set B. The final result is B.
Div # A P
# A generally only has one, so the range of P in Case 1 is too large. Therefore, if the first selection expression contains an ID, sizzle always searches for the first one first to narrow the search range.
Case 2: First find Div # A, obtain a single element A1, and then search for P in the environment of A1. the final result B1 is obtained.

Therefore, the final process becomes

1. Split expression
2. Search for elements
Third, filter elements (filtering is divided into two types. 1. filter elements by their own attributes. 2. filter elements by relationship between elements .)

Therefore, we can obtain the approximate code structure of sizzle:
Basic Structure of sizzle Engine
Main process: window. Sizzle = function (){};
Search element: sizzle. Find = function (){};
Filter element: sizzle. Filter = function (){};

Define some search methods and filtering conditions used: sizzle. selectors = {};
Sizzle. selectors is often used, so a short name is called expr.

The code framework of sizzle is as follows:

Window. Sizzle = function (){
// Mainly responsible for the process of chunking and main line, and filtering by the relationship between elements is also placed in this part
};
Sizzle. Find = function (){
// Search for elements
};
Sizzle. Filter = function (){
// Filter elements, mainly used to filter elements by their attributes
};
Sizzle. selectors = {
// Namespace and some variables and specific methods
};
VaR expr = sizzle. selectors; // alias

The remaining question is how to obtain the set of elements we need.

 

Preliminary Discussion on searching Elements

Let's first look at how to find elements. There are only three native ways to find elements in the browser.
(At the beginning of this article, we assume that all browsers initially do not support getelementsbyclassname, although most of them support it ):
Getelementbyid, getelementsbyname, and getelementsbytagname.

Question 1:
When we encounter a selection expression, how can we determine the type of the selection expression.
Solution:
Check the type of the expression in sequence to obtain the matching type. Note that once the matching type is obtained, the matching will not continue.
As to which type to match first, the search principle is to narrow the search scope as much as possible (the higher the specificity, the smaller the search scope ). Generally, the number of IDS is smaller than the number of names, and the number of names is smaller than the number of tags. Therefore, the order of determination is ['id', 'name', 'tag'].
Instance description:
1. Input [name = "test"], first look for [name = "test"]. At this time, although you can continue to look for input, there is no need for that, if the intersection is obtained after the input is queried, the program structure is damaged.
The Processing Method of sizzle is: first query [name = "test"] to obtain the Set A, then filter the input in a, and the input is thrown to the filtering part as a filter condition.

2. Input # demo [name = "test"] Because the priority of the ID is higher than that of the name, search for # demo to obtain a set, then, input [name = "test"] is filtered out in a, and input [name = "test"] is thrown into the filter part as a filter condition for processing.

Preliminary Discussion on filter elements

Filtering is performed by a condition and a condition. For a set a and a filter expression

expr='[class="test"][rel=1]:first-child'

Filter [class = "test"] In a to obtain the Set B. In this case, the filter expression expr = '[rel = 1]: First-child'
Filter [rel = 1] In B to obtain the set C. In this case, the filter expression expr = ': First-child'
Filter in C: First-child gets the set D. In this case, the filter expression expr = ''. The filter is complete.

[Note]
The filtering is divided into two steps:
1. pre-filter expr. prefilter: Processing compatibility issues and format conversion determines the next step
First, the final filter expr. filter, the form of this step is the same, and the final return is a Boolean value.

Filtering Method:

Suppose the filtering set in the first round: A = ['# 1',' # 2', '# 3',' # 4', '# 5',' # 6']
The filter condition is ismatch.
The set that meets the condition is c = ['# 1',' # 2', '# 3']

First,

var B = [];
for( i = 0; (item = A[i]) != null; i++ ){
A[i] = isMatch(item);
}
for( i = 0; i < A.length; i++ ){
if(A[i]){
B.push(A[i]);
}
}

1. ['# 1',' # 2', '# 3',' # 4', '# 5',' # 6']
2. ['# 1',' # 2', '# 3', false]
3. ['# 1',' # 2', '# 3']

Second,

var B = [];
for( i = 0; (item = A[i]) != null; i++ ){
if(isMatch(item)){
B.push(A[i]);
}
}

Next is the main process and necessary Regular Expression Analysis: sizzle engine-Principles and Practices (II)

 

For more information, see http://www.cnblogs.com/xesam /]
Address: http://www.cnblogs.com/xesam/archive/2012/02/15/2352466.html

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.