Mini,又个 Javascript 选择器September 16, 2009
Javascript 选择器(selector engine)似乎从 jQuery 流行以来就大行其道,改变了原有 Javascript 选择 DOM 节点的方式。
目前 Javascript 选择器也有众多的选择,包括能列举出来的就有 Peppy、 Sizzle 以及 Sly 等,它们都实现了所有的 CSS3 选择器并且性能不俗。

而此次特别要推荐 Mini 的因素有很多。其最大的亮点就是从实用主义出发,简单高效的完成任务。
实用主义
jQuery 的作者 John Resig 曾经统计 jQuery 框架常用的几个选择器。 很惊讶的发现用户其实常用 tagName、className 以及 id 就能完成 95% 以上的工作。
而 Mini 就从实用出发,它并没有标榜自己实现了全部 CSS3 的所有选择器,只是实现了下面的选择器及其变种:
- div
- .example
- body div
- div, p
- div, p, .example
- div p
- div > p
- div.example
- ul .example
- #title
- h1#title
- div #title
- ul.foo > * span
是的,虽然不多,但是相信在日常中已经足够使用。

实用主义虽然让 Mini 提供的功能有限,但从个侧面带来的优势就是 性能方面非常的理想。 当然这还有与它的内部实现有关。
简单至上
Mini 的代码很简单,甚至不用恐惧于如何去读懂 Sizzle 这样的每行源代码。先从它的调用函数 _find 看起,往下阅读几行,你就发现它性能的秘密
if (!simple && context.querySelectorAll) {
return realArray(context.querySelectorAll(selector));
}很多的现代浏览器(包括 Gecko、WebKit 等)都 提供了原生的 Javascript 选择器支持。 Mini 充分得利用了这点,从而将大部分的工作交给了浏览器(也免除了日后的维护之忧)。这点非常值得称道, 也是我们以后写 Javascript 应该走的方向 -- 要基于浏览器提供的功能而非类型进行对应的开发。
_find 其后的逻辑非常的简单,使用几个正则将提供的选择器解析出来,分别根据 getElementsByClassName、 getElementsByClassName 以及 getElementById 获取节点。
继续根据上面的思路,由于陈旧的 IE 没有既没有提供 querySelectorAll 也没有提供 getElementsByClassName, 那么它只能走到 else 的尽头,使用 filterByAttr 函数。
取到对应 className 以及 tagName 后,还得根据选择器获取其与其相符的节点,那么就轮到 filterParents 干活了。
filterParents 这个函数也是相对 _find 比较核心的函数,而且也是主要的性能消耗点。filterParents 其实要做的和 _find 类似,唯一不同的是它根据关系符向上剔除未满足条件的节点。
通过上面两个函数所得到的节点,通常已经是满足选择符条件的节点了。 但是可能的情况就是有重复的节点,这时就该 unique 函数上场,顾名思义剔除重复的节点。
这里要提到的就是 unique 函数做了个简单的 memoization 实现, 作者的用心可谓从细节方面体现得淋漓尽致。还有个小技巧就是
var uid = +new Date();
竟然可以用这样直接返回时间戳,俏皮的代码让人再次感到犹如嚼了口薄荷糖,非常的清新(好吧,我火星了)。
读码到最后,有一点思考就是为何每次都要使用 realArray 函数强制将 NodeList 转换成 Array?虽然使用 querySelectorAll 返回的是 NodeList ,但是也是可以使用 Array 操作迭代。作者这样的做法我推测,可能是出于返回数据类型一致的缘故。
观点
说说到我的个人观点,这可能会让这篇文章前后矛盾。Javascript 选择器(selector engine)我个人不是非常推荐使用。
原因主要有两点,其一就是性能,其二就是会让写出来的代码过于的依赖于 DOM 结构。但能读到如 Mini 这样的代码,窥其内部运作机制,未尝不是件非常让人愉悦的事情。

最后,说说 Mini 的作者 James Padolsey 。我本人也很难相信,他竟然只有 19 岁!更难 得的是在他 Blog 上的 About me 页面中写道
What services do I currently offer? - Everything JavaScript!
同时,他也是 jQuery Cookbook 的作者。 “小小年纪”能够有这样的心态以及成就,让我们这帮“前端老古董”感到唏嘘不已 :^)
这家伙真牛b,真实年轻又有为呀,让我等大龄青年汗颜
一不小心把名字写成blog的url了 :(
看了一下源码只有1.5k,这个很不错~
弄下来学习学习!
[...]Mini,又一个 Javascript 选择器 【JavaScript】http://www.gracecode.com/archives/2981/[...]
佩服一个
别看只有19岁 很可能折腾程序的年份比你我都久
[...]在网上发现一个JavaScript小型选择器—mini,其介绍在这里已经说得挺清楚了,就不再罗嗦了。简单来说,mini选择器只支持以下选择语句:[...]
不错,研究一下呵!
[...]在网上发现一个JavaScript小型选择器—mini,其介绍在这里已经说得挺清楚了,就不再罗嗦了。简单来说,mini选择器只支持以下选择语句:[...]
网站风格真不错,很简洁。