js selector设计及实现(一) 实现思路

本文详述了JavaScript选择器的设计思路与实现过程,包括为何需要选择器、选择器的接口、支持的选择器类型、解析表达式的步骤,并提供了代码示例。作者还分享了自己在实现一个名为Fox的查询接口时的思考,旨在帮助读者理解和实现自己的选择器。
摘要由CSDN通过智能技术生成

前阵子和伟大的JK同学学习了一下目前我们框架里新版本的selector,这里列的是第一版selector的代码思路。
后一版本调优性能,多了些函数,从性能上与各大框架比还是有竞争力的。

说句实在话,虽然各大框架和库都实现了selector。但看他们的selector实现其他的人看上去无疑都是难看懂。
而google,baidu上query出的结果基本都是说使用方式的文章,基本没有类似针对selector设计和具体实现上的文章。
所以,决定将整个思路和实现写出来,一来是增加印象,二来是给目前想写的人以参考。

我是以我学习及写selector的角度及把我向JK学习思路和我自己的设计,代码写的思路写出来。
这篇文章我也想不到写了这么长。建议这么看比较好:

  • 不熟悉selector用户先去熟悉了休息会,再看此文;文中没有写详细的selector的具体内容,只是为了描述,大略的提了下;
  • selector了解了之后再看看思路;顺序解析还是比较容易看懂的;
  • 后文中的js代码里,我做了详细的注释,结构也和文中提的代码结构一样,有兴趣的同学可以读下,这个selector代码暂名为:Fox,接口为Fox.query(selector, context)。

代码可以点这里下载和测试
此份代码已经注释,比较简单,我没去写优化的代码,之所以代码里面不写,是因为写了解释起来很绕,熟悉思路先吧,以后详细优化的文章及代码可以抽空再写。

OK,开始吧。

 

为什么有selector?

selector原来是用于CSS开发时方便样式与结构分离的策略。
而在如今做JS/DOM开发的时候,绝大部分的代码之一都是选择目标元素/集合。
在XML里有XPATH来实现该功能;同理的,在JS/DOM开发时自然出现了selector。

现在selector的火很大程度上除了需要感谢国家,还要感谢jquery。它如同当年Prototype带来了Ruby风格,一大批的前端开发人员都投入到jquery的怀抱。给了很多前端开发人员以快速上手,插件copy的方式来开发前端程序。
jquery是推进selector使用的催化剂。现在很多浏览器都支持了selector,但各实现都不尽相同,所以做一个适合自己的selector目前来看是有必要的。

selector简单实用,减少无技术含量的工作。
还可以重新约束一下前端的UI框架,在render接口不是耦合HTML结构,而是与CSS selector做为桥接
具体可以点这里可以看我之前写的一篇文章(降低HTML结构与脚本之间的强耦合),这里不再多述。

selector的应用接口

selector提供给外部的接口应该尽量遵循标准。开放的接口应该包括:

  • document|element.querySelector(str)
  • document|element.querySelectorAll(str)

举例说明:

 
 
var element  = document. querySelector (selectors ) ;
var matches  = document. querySelectorAll ( "div.note, div.alert" ) ;

具体在代码里的表现形式

Fox.query(selector, context);

selector及其类型

selector是一种选择DOM元素/集合的一种符号。它包括以下的类型:

  • 包括通配选择符——*
  • 类型选择符——如E { sRules }
  • 属性选择符——它包含四种等式:
    • E[attr] 选择具有 attr 属性的 E
    • E[attr=value] 选择具有 attr 属性且属性值等于 value 的 E
    • E[attr~=value] 选择具有 attr 属性且属性值为一用空格分隔的字词列表,其中一个等于 value 的 E 。这里的 value 不能包含空格
    • E[attr|=value] 选择具有 attr 属性且属性值为一用连字符分隔的字词列表,由 value 开始的 E
    • E[attr^=value] 选择具有 attr 属性开始的值为value的 E
    • E[attr$=value] 选择具有 attr 属性结尾的值为value的 E
    • E[attr*=value] 选择具有 attr 属性里包含value的E
  • 包含选择符(祖先)——如E1 E2 选择所有被 E1 包含的 E2 。即 E1.contains(E2)==true 。
  • 子对象选择符——如E1 > E2 选择所有作为 E1 子对象的 E2 。
  • ID选择符——#ID { sRules } 以文档目录树(DOM)中作为对象的唯一标识符的 ID 作为选择符。
  • 类选择符——E.className { sRules } ,它是属性选择符的一种简写形式。其效果等同于E [ class ~= className ] 。
  • 伪类选择符——E : Pseudo-Classes { sRules } JS selector里取到的伪类有如下几种:

    “first-child”,”last-child”, “only-child”,”nth-child”,”nth-last-child”,”first-of-type”,”last-of-type”,
    “only-of-type”,”nth-of-type”,”nth-last-of-type”,”empty”,”parent”,
    “not”,”enabled”,”disabled”,”checked”,”contains”

  • 伪对象选择符。E : Pseudo-Elements { sRules } 这在JS selector里可不实现(在DOM树里无法找到)

开发完的代码已支持的selector表

*
E
E F
E > F
E + F
E ~ F
E.warning
E#myid
E:first-child
E:last-child
E:nth-child(n)
E:nth-last-child(n)
E:only-child
E:enabled
E:disabled
E:checked
E:contains(“foo”)
E:not(s)
E[foo]
E[foo="bar"]
E[foo~="bar"]
E[foo^="bar"]
E[foo$="bar"]
E[foo*="bar"]
E[foo|="bar"]

使用示例:

 
 
  1. alert(Fox.query('div~div', document.body).length);  
  2. alert(Fox.query('div~div.aa', document.body).length);  
  3. alert(Fox.query('div span', document.body).length);  
  4. alert(Fox.query('div div', document.body).length);  
  5. alert(Fox.query('div
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值