狄烁STEC的试验场

hello earth

导航

制作JavaScript选择器(2)查询链

上回实现了将选择器解析为令牌,下面就要实现轮子的核心:令牌转换为查询链。

在描述查询链之前先定义伪代码:

操作 解释
getNode() 获取全部节点
filterAncestor() 过滤祖先节点
childNode() 获取子节点
filterParent() 过滤父节点
nextNode() 获取后一个紧邻的兄弟节点
filterPrev() 过滤前一个紧邻的兄弟节点
nextAllNode() 获取后面的兄弟节点
filterFront() 过滤前面的兄弟节点
uniqueNode() 去除重复

简单的查询链有两种,即从左到右和从右到左。

从左到右:

  1. 对每一个选择器子组进行以下操作
    1. 解析最左边的简单选择器,getNode
    2. 如果右边还有剩余部分,则根据连接符不同,对当前结果使用 getNode、childNode、nextNode 和 nextAllNode 其中一个
    3. 重复第二步,并对每次结果使用 uniqueNode 去除重复,直到结束
  2. 合并每个子组的结果,然后 uniqueNode 去除重复

从右到左:

  1. 对每一个选择器子组进行以下操作
    1. 解析最右边的简单选择器,getNode
    2. 如果左边还有剩余部分,则根据连接符不同,继续使用 filterAncentor、filterParent、filterPrev 和 filterFront 中的一个,直到结束;
  2. 合并每个子组的结果,然后 uniqueNode 去除重复

上一篇文章提到我打算使用分部查询,具体的操作就是只对“>”、“+”、“~”这三个连接符使用从左到右查询,对“ ”连接符采用从右到左查询。

对选择器 "A B C > D E F ~ G H"来说,从左到右可以描述为:

context
.getNode(A)
.getNode(B).uniqueNode()
.getNode(C).uniqueNode()
.childNode(D).uniqueNode()
.getNode(E).uniqueNode()
.getNode(F).uniqueNode()
.nextNode(G).uniqueNode()
.getNode(H).uniqueNode();

从右到左为描述为:

context
.getNode(H)
.filterAncestor(G)
.filterPrev(F)
.filterAncestor(E)
.filterAncestor(D)
.filterParent(C)
.filterAncestor(B)
.filterAncestor(A);

我的计划描述为:

context
.getNode(C)
.filterAncestor(B)
.filterAncestor(A)
.childNode(D)
.getNode(F)
.filterAncestor(E)
.nextNode(G)
.getNode(H)

基于令牌的伪查询链生成器http://dishuostec.sinaapp.com/javascript/css_token/parse/

示例:

选择器
查询串
* context.getNode( < * > )
body div context.getNode( < div > ).filterAncestor( < body > )
h1#title + div > p context.getNode( < #title, h1 > ).childNode( < p > )
div p a context.getNode( < a > ).filterAncestor( < div >,< p > )
div, p, a unique( context.getNode( < div > ) , context.getNode( < p > ) , context.getNode( < a > ) )
context, 

posted on 2011-07-02 12:11  狄烁STEC  阅读(226)  评论(0编辑  收藏  举报