A css3 selector engine implementation based on matching and rollback.
Introduction
CSS selector is a specific micro-syntax used in DOM node search scenarios. It is essentially a pattern matching language like regular expressions. It can be used flexibly to obtain a node set at a specified position.
The W3C recommendation standard is Selectors Level 3, which is basically consistent on ie9 +, firefox, chrome, mobile and other browsers, while javascript is required for simulation in ie, this article describes the implementation of a css3 selector Engine Based on matching and rollback, which is applicable to ie6.
Syntax
Css selector is a compact syntax. According to css3 specifications, a selector string is first composed of a group separated by commas (,). For example
s = g1,g2
Indicates a set of elements matching g1 and g2. The group consists of '', '+', '> ','~ 'Split the simple selector sequence, for example
g1 = simple1 + simple2g1 = simple1 simple2g1 = simple1 > simple2g1 = simple1 ~ simple2
+It indicates that the elements matched by simple1 are in the same level as those of simple2, and the elements of simple2 follow simple1.
>Indicates that the elements matched by simple2 keep up with the next level of simple1.
' 'Indicates that the elements matching simple1 are closer to the root node than the simple2 hierarchy.
~Indicates that the elements matching simple1 are at the same level as those of simple2.
A simple selector sequence can also be composed of a type selector and a suffix selector, for example
simple1 = type_selector suffix_selector
TypeSelector indicates the tag name, such as 'h1 'and 'h2 '. If this parameter is not specified, the default value is '*', indicating that any tag is matched. SuffixSelector is generally used for further filtering, such as class selector (specifying class names), attribute selector (limiting attributes), pseudo classes, and pseudo elements.
For exampleh1.xMatch
But does not matchOr<span class='x'>.
You can view the w3c standard page for the complete syntax description.
This syntax is abstracted
a.b + c.d ~ e.f
Where a c e is the type selector, B d f is the suffix selector, and + represents the direct positional relationship> + ,~ Representing the fuzzy location relationship ~ ''.
Implement parser generation
First, use the css selector syntax to generate a parser using the LALR Parser Generator, which can convert the string format of the selector into structured data. Kison is used for generation.
The kison format of the css selector syntax is described as follows: selector-grammar
The generated parser code is as follows: parser. js
The flowchart is as follows:
The parsed structured data is in two-way linked list format, for example
a.b + c.d
The resolved linked list is:
Engine search
The next step is engine search. The search process is complex. The following describes the process based on the following flowchart:
The example selector string is:
a.b + c.d ~ a + e.f
Matching node string:
e.f a.b c.d e c.d e a e.f
Obtain a seed set
Similar to the general browser implementation, the method of searching from the right to the left is used. First, you need to obtain the seed set from the type selector on the rightmost side. According to this example:
a e.f a.b c.d e c.d e a e.f ^ ^ ^ ^
Selector Linked List Group
Group the selector based on the direct position, and combine the simple selector sequence connected by the direct position into a group.
a.b + c.d ~ a + e.f--------- -------
Grouping means that each matching operation matches the group directly connected to each other as a unit, and the group should also be used as a unit to return to the group (it is meaningless to return to the group directly at the position ).
Preliminary seed Filtering
Based on the selector sequence of the last group:
a + e.f
Further filter the seed set, which is:
a e.f a.b c.d e c.d e a e.f ^ ^ 1 2
Further filter Seeds
In this step, the seed will be further filtered, and the filter process may even return.
For example, for the first seed, after preliminary filtering, the node string cursor and the selector cursor are
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
Because the cursor of the node string has crossed the node string header, the match fails and the match of the seed node fails.
For the second seed, after preliminary filtering, the node string cursor and the selector cursor are
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
The matching fails, but the selector link is '~ ', Move the node string cursor instead of the selector cursor:
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
You can continue to match:
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
At this time, because the selector link is '+', it is impossible to match the cursor of the moving node string again. At this time, the selector cursor should be rolled back to the front of the group:
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
At this time, the match still fails, but you can move the node string cursor:
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
In this case, you can match the selector cursor to the header:
a e.f a.b c.d e c.d e a e.f ^ a.b + c.d ~ a + e.f ^
It indicates that the seed node matches the selector string and the number of matched nodes is 1.
a e.f a.b c.d e c.d e a e.f ^
Engine Code
For more information about the engine code, see selector. js.
Unit Test
The unit test pulls the part of sizzle corresponding to css3 directly. After a few adjustments, all of them pass:
Selector-sizzle Test
Performance Testing
Kissy-selector-sizzle
You are welcome to submit a new example.
Which one can give an example of a new property selector in the CSS 3 selector of html 5?
"Example:
A[href000000000000.html "] match all hyperlinks ending with. html.
Div [id * = "primary"] matches all the div IDs that contain primary.
For more information, see a recent tutorial. The video series named "Buid New World" contains the eighth set of CSS3 selectors. For more information, see"
Use the CSS3 selector to create a rounded corner of the drop-down menu. You need to change the color of the line and write it by yourself.
When I saw the sentence "please write it by yourself", I felt very strange. Did you come to the exam? Or are you looking for answers? However, to answer this question, let's take a look at it first:
There are many ways to do this. You can use select or simulate it. The code for the rounded corner is:
Border-radius: 10px;
Line-by-line color change code:
$ (". Txt_list li: odd" ).css ("background", "# ccc ");
$ (". Txt_list li: even" ).css ("background", "# fff ");