W3C Selector API将为JavaScript开发注入新活力
今天,向大家介绍DOM脚本编程领域一项令人激动的进步——W3C Selector API。迄今为止,在使用DOM2级API的前提下,要想从DOM中取得HTML元素,只能使用document.getElementById,或者使用document.getElementsByTagName然后再手工编码进行筛选。随着CSS的普及,JavaScript开发人员不断提到一个显而易见的问题:“为什么浏览器不能提供一种快捷方法,用来选择与CSS选择符匹配的HTML元素呢?”
于是,上述Selector API定义了querySelector和querySelectorAll方法,它们就以CSS选择符为参数,分别返回匹配的第一个元素和所有匹配元素的StaticNodeList(静态节点列表)。这两个方法既可以通过document对象调用,以便在整个文档范围内查询目标元素,也可以通过个别的HTML元素调用,以便只在该元素的后代元素中查询目标元素。
下面我们看一个简单的HTML示例,以此演示如何使用Selector API:
- <ul id="menu">
- <li>
- <input type="checkbox" name="item1_done" id="item1_done">
- <label for="item1_done">bread</label>
- </li>
- <li class="important">
- <input type="checkbox" name="item2_done" id="item2_done">
- <label for="item2_done">milk</label>
- </li>
- <!-- 更多列表项 -->
- </ul>
我们的任务是通过脚本选中所有类名为“important”的列表项中的复选框(checkbox)。如果使用DOM2级API的方法,可以这样来做:
- var items = document.getElementById(
- 'menu'
- ).getElementsByTagName(
- 'li'
- );
- for(var i=0; i < items.length; i++) {
- if(items[i].className.match(/important/)) {
- if(items[i].firstChild.type == "checkbox") {
- items[i].firstChild.checked = true;
- }
- }
- }
而使用新的选择符API,则可以将上面代码简化为:
- var items = document.querySelectorAll(
- '#menu li.important input[type="checkbox"]'
- );
- for(var i=0; i < items.length; i++) {
- items[i].checked = true;
- }
是不是更简单方便了?注意,querySelector和querySelectorAll方法还支持组合选择符——即由逗号分隔的多个选择符。目前,将会支持Selector API的浏览器包括Safari3.1、IE8 beta、Firefox3.1。Opera也在积极添加对该API的支持。
假如读者擅长使用各种JavaScript库,那么心里可能会暗自嘀咕:“这些我通过库早就能做到了呀?”事实上,很多人使用各种JavaScript库的原因在很大程度上恰恰是因为这些库实现了通过CSS选择符的查询机制。最近,由于这些库作者们共享了他们的技术,我们发现CSS选择符查询速度又有了明显的提升。那么,使用Selector API还有什么必要呢?一言以蔽之:速度——本地实现的优势就是速度!而且,所有这些JavaScript库都非常看重这一点。jQuery和Prototype正在向使用Selector API的路线上靠拢,而Dojo Toolkit、DOMAssistant和base2则已经在使用该API了。
这3个库之所以能首批利用该API是有原因的。Kevin在他的博客文章“Is Your JavaScript Library Standards Compliant?(你的JavaScript库与标准兼容吗?)”曾专门讨论过这些问题。由于Selector API要求使用标准的CSS选择符,因此如果浏览器不支持某种选择符,那么就无法使用该选择符。这些已经开始利用Selector API的库都是原先只支持标准CSS选择符的。对于这些库而言,支持该API(几乎)就相当于添加如下代码:
- if(document.querySelector) {
- return document.querySelector(selector);
- } else {
- return oldSelectorFunction(selector);
- }
但是,那些支持自定义选择符的库要支持Selector API则远没有那么简单。首先,如果开发人员已经在自己的项目中大量使用了自定义的CSS选择符,那么要想通过该库获得速度提升会很困难,因为这些库必须使用其默认选择符而不能使用Selector API。其次,即使这些库采取某种措施解决了使用自定义选择符的问题,从而支持了Selector API,但该库也必须面对体积增大的风险。
理想的状况下,Selector API是想鼓励人们使用标准CSS选择符,放弃使用自定义选择符。事实上,如果新版的浏览器都能做到足够好,而且新Selector API的性能提升也足以令人侧目,那么自定义选择符功能很可能就会自动转移到辅助库中,而且只在处理遗留代码的兼容性问题时才会用到。
我个人认为,Dean Edwards的base2库实现得最好的。因为base2完全实现了该API,也就是说,开发人员使用base2编写JavaScript时尽可以使用标准的API方法——因为base2只在浏览器不支持标准API时,才会创建querySelector和querySelectorAll方法。这已经是一种非常理想的状态了。但是,不管怎样base2还是在其自定义选择符功能中实现了非标准的“!=”属性选择符(显然是迫于同行的压力),因此在这一点上也有所失分。
无论你是使用还是在编写JavaScript库,新版浏览器对Selector API的支持必将给所有人的开发工作带来直接的性能提升。换句话说,我们都将是受益者,万岁!
Dojo之父Alex Russell在《Mastering Dojo》中为自己的工具箱所作的“广告”:
Dojo基于兼容未来标准的原则而构建,这些标准最终会在所有浏览器中实现,届时开发人员将可以使用又快又简单的本地方法。dojo.query方法就是一个非常好的例子。W3C Selectors API标准描述了一个通过CSS选择符来查询DOM树的API,该Web API工作组规定了一个编程用的方法,即querySelectorAll。querySelectorAll方法和dojo.query方法一样,都返回一个节点数组。虽然Dojo的CSS查询引擎速度很快,但通过让查询语法与CSS语法保持一致,有效地解决了始终要依赖该引擎的问题。事实上,在完全支持上述API的浏览器中,Dojo会使用querySelectorAll方法。相信dojo.query成为querySelectorsAll的包装方法只是迟早的事——只不过通过包装它还会为返回的节点数组添加一些甜美的语法糖(syntactic sugar)。最好的结果,就是上述API成为真正的标准,不再改变,开发人员也会因此全都享受到由C++实现的查询引擎的快捷与便利,同时,更不会因向后兼容问题而感到烦恼。对于Dojo用户而言,选择这个关注Web未来发展的工具箱,就等于已经享受到了上述好处。
事实上,Alex Russell确实是W3C Selector API的一个重要建议人。
同css2/3 selector一样,让人爱,又爱不起来,只能先看看,流流口水。
不过这个玩意儿什么时候才能得到广大浏览器厂商的完全支持啊?
目前还是使用js库方便一些,
速度方面的差异,
应该可以忽略不计吧?
鉴于目前网络日益多样化和复杂化,我们在中国首次组织了网络标准沙龙以讨论开放网络标准以及网页开发技术,本沙龙仅为技术交流,禁止任何商业宣传。 ”
本次沙龙参与者有来自伦敦的 Henney Swan (W3C ILG co-lead)、来自挪威的 Zibin Cheah (Web Evangelist at Opera Software),以及一些业内人士。
如果您对于本沙龙感兴趣,可以参与到我们的讨论中。今后我们会不定期的组织沙龙聚会。
本次沙龙主题:Web 2.0 时代网页风格设计及用户体验
时间:10 月 18 日 下午 3 点
地点:lush 酒吧 (海淀区五道口成府路35号华清嘉园光合作用2楼旁边)
本次活动由Opera赞助。
抱歉,周六(18日)有其他事,无法参加。
谢谢 受益匪浅啊
ad ~~
开发者资讯 | 我们致力于为开发者提供动力!
欢迎你的到来!
http://jacken.com.cn
嘻嘻