狄烁STEC的试验场

hello earth

导航

制作JavaScript选择器(1)解析令牌

JavaScript选择器有很多,大到sizzle小到mini,再加上各种框架各种库,可以说高低胖瘦各有不同。一直以来都想亲手做一个选择器,虽说现成的轮子到处都有,但不懂造轮子的前端不是好攻城师啊。可是无奈精力有限,而且现成的轮子都很好使,这个想法就被一拖再拖。

闲话不多说...

选择器的原理大致如下:

  1. 分析得到的 selector 文本,如果是分组的选择器则拆开;
  2. 根据 selector 从左向右依次查询,然后去重(或从右向左依次过滤,不需要去重);
  3. 对剩余的选择器组执行第2步,合并结果;
  4. 结果去重。

我的轮子设计如下:

  1. 将得到的 selector 文本解析为令牌数组及对应的参数数组;
  2. 根据令牌生成查询语句串并缓存,以备重复使用;
  3. 执行查询语句串,返回结果。

可以看出重点在查询语句串的生成,查询顺序计划采用分部查询,而不是单纯的从右向左。

根据设计先做出 selector 令牌解析器:http://dishuostec.sinaapp.com/javascript/css_token/

解析器获取 selector 选择器然后解析,返回一个长度为2的数组 T,T[0]为令牌数组,T[1]为参数数组。

示例:

选择器 令牌 参数
#title [ID] ['title']
div[class] [TYPE, ATTR_HAS] ['div', class]
div[class=example] [TYPE, ATTR_MATCH] ['div', ['class', 'example']]
div[class^=exa][class$=mple] [TYPE, PREFIXMATCH, SUFFIXMATCH] ['div', ['class', 'exa'], ['class', 'mple']]
ul .tocline2 [TYPE, CONBI_DESCENDANT, CLASS] ['ul', null, tocline2]
body div [TYPE, CONBI_DESCENDANT, TYPE] ['body', null, 'div']
div > p [TYPE, CONBI_CHILD, TYPE] ['div', '>', 'p']
div ~ p [TYPE, CONBI_GENERAL_SIBLING, TYPE] ['div', '~', 'p']
div, p, a [TYPE, GROUP, TYPE, GROUP, TYPE] ['div', ',', 'p', ',', 'a']
h1#title + div > p [TYPE, ID, CONBI_ADJACENT_SIBLING, TYPE, CONBI_CHILD, TYPE] ['hi', 'title', '+', 'div', '>', 'p']

posted on 2011-06-29 17:43  狄烁STEC  阅读(389)  评论(0编辑  收藏  举报