在本篇文章中,咱们将了解DOM的查询以及如何运用dojo/query这个模块来轻松地选择节点并操做他们。javascript
入门指南php
在操做DOM的过程当中,如何快速高效地检索出DOM节点显得至关重要。咱们在Dojo DOM Functions中已经熟悉了 dom.byId,然而,在应用程序里找出每个感兴趣的节点的惟一ID是项繁琐且易错的工做。而且仅靠ID的方式来选择大量节点的效率可见是低下的。因此,这里介绍另外一个解决方案:dojo/query。dojo/query模块使用相似CSS查询方式(你常在样式表里使用的方式)来检索一列节点,模块也支持高级的CSS3选择器!css
查询html
为了举例说明一些最经常使用的查询,咱们将用到下面的HTML,若是在你的网站里用到一列的连接,那么你可能会使用到下面的HTMLjava
<ul id="list"> <li class="odd"> <div class="bold"> <a class="odd">Odd</a> </div> </li> <li class="even"> <div class="italic"> <a class="even">Even</a> </div> </li> <li class="odd"> <a class="odd">Odd</a> </li> <li class="even"> <div class="bold"> <a class="even">Even</a> </div> </li> <li class="odd"> <div class="italic"> <a class="odd">Odd</a> </div> </li> <li class="even"> <a class="even">Even</a> </li> </ul> <ul id="list2"> <li class="odd">Odd</li> </ul>
你第一件想作的事就是获取整个列表。咱们从前面的知识知道,你可使用 dom.byId,但这里你能够用 query,乍一看,这种方式的做用并不明显,但咱们能够从下面的例子中学到更多:node
// require the query and domReady modules require(["dojo/query", "dojo/domReady!"], function(query) { // retrieve an array of nodes with the ID "list" var list = query("#list")[0]; })
经过在某个标识符前面加个 "#",咱们告诉query去查找包含这个ID属性的节点集。这种匹配习惯和CSS类似。须要注意的是: query始终返回数组对象。在后面咱们将进一步了解这种数组,可是咱们知道,只有一个(也只能有一个)节点的ID为"list",咱们将他从数组中取出。css3
根据ID获取节点是不错的一个方式,但使用 dom.byId的效率将更好。但query容许你经过css样式名来选择节点。例如咱们想获取那些样式为"odd"的节点:数组
// retrieve an array of nodes with the class name "odd" var odds = query(".odd");
经过在标识符前面加上 ".",咱们告诉query去查找那些样式名包含标识符的节点。再次说明,这个样式表匹配类似。在上面的例子中,query将会返回一个包含4个li节点和3个a节点。浏览器
限定你的查询dom
你可能已经注意到上一个例子中的odds查找出的结果中包含了两个列表中的节点。若是咱们只想获取第一个列表中的odds节点,咱们有两种方式:
// retrieve an array of nodes with the class name "odd" // from the first list using a selector var odds1 = query("#list .odd"); // retrieve an array of nodes with the class name "odd" // from the first list using a DOM node var odds2 = query(".odd", document.getElementById("list"));
不一样的方式获取的两个数组中包含一样的结果:第一种是经过选择语法在全部DOM中限制结果输出,第二种是限制查询引擎在特定的DOM中查找结果。
当query执行时不带第二个参数,它将搜索整个DOM结构,便利html标签下的全部节点。当第二个参数制定为某个节点时,它将搜索范围限制在这个节点下。
若是你的DOM相对比较小,就像例子中的,省略第二个参数是可行的。但当页面中的DOM结构至关大是,最好加入第二个参数来限制查询范围。这样作比在整个文档中查找得更快。
剩下的例子中,咱们将省略第二个参数,但在使用query的时候请注意--保持你的代码运行得更快和更好的用户体验。
高级查询
咱们前面的查询结果中混合了li标签和a标签,但若是咱们只关心a标签时怎么作呢?你能够将标签名和样式名合并起来:
var oddA = query("a.odd");
对比分割标识符(表明了等级关系),你能够将标识符和目标节点合并起来;这里包含样式名称,可使用query查询
另外一种选择器能够跨浏览器,但不是在全部样式里都支持,就是">",这中选择器只查询第一个选择器下的第二个选择器。举个例子:
// Retrieve an array of any a element that has an // li as its ancestor. var allA = query("li a"); // Retrieve an array of any a element that has an // li as its direct parent. var someA = query("li > a");
allA包含6个a标签而someA将只包含2个a标签,任何一个选择器均可以在">"的右边,包括CSS选择器。咱们如今只涉及到了一些经常使用选择器,query彻底支持CSS3而且兼容你本身可能会遇到的其余选择器
节点集合
咱们以前提到过,query返回一个符合选择器的节点数组;这个数组就是 dojo/NodeList而且数组包含能够和节点交互的方法。上一个例子就用到了几个方法,如今让咱们看看一些你极可能在你程序里用到的方法。为了辅助例子,咱们须要如下的HTML:
<div id="list"> <div class="odd">One</div> <div class="even">Two</div> <div class="odd">Three</div> <div class="even">Four</div> <div class="odd">Five</div> <div class="even">Six</div> </div>
dojo/NodeList拥有一些和Dojo array helper类似的方法。例如ForEach,它会为数组中的每一个节点都运行一次函数。
// Wait for the DOM to be ready before working with it require(["dojo/query", "dojo/dom-class", "dojo/domReady!"], function(query, domClass) { query(".odd").forEach(function(node, index, nodelist){ // for each node in the array returned by query, // execute the following code domClass.add(node, "red"); }); });
一个函数会传给forEach,一般叫作回调函数,数组中的每一个元素都会调用这个函数,而且带入下面的参数:node表明当前节点,index表明节点的索引,NodeList则表明这个数组。对于大部分开发组来讲,第三个参数能够忽略;但在某些数组不太容易获取的状况下(例如本例中),第三个参数则有助于获取数组中的其余元素。forEach方法也能够接收第二个参数来制定回调函数的执行域。
其余的一些NodeList的array helper方法为:map,filter,every和some。除了every和which返回的是布尔类型外其余的方法返回的都是NodeList。
还有一些扩展模块经过增长其余的方法到NodeLists来扩展NodeLists的能力。class和style帮助方法在 dojo/NodeList-dom。 dojo/NodeList-dom提供了一些符合Dojo操做DOM的方法,因此以前的例子能够简化:
require(["dojo/query", "dojo/NodeList-dom", "dojo/domReady!"], function(query) { // Add "red" to the className of each node matching // the selector ".odd" query(".odd").addClass("red"); // Add "blue" to the className of each node matching // the selector ".even" query(".even").addClass("blue"); });
事件
NodeList提供的另外一个快捷方法是on,用来链接DOM的事件。尽管写一篇文章将讲到DOMN事件,咱们这里了解一下使用NodeList的on方法。这里须要注意的是尽管这是一个方便的方法,但尽可能不要在包含大量节点的节点数组中使用这种方法;一种叫 event delegation的技术能够在那种状况下使用,这种方法将在events tutorial中讲到。
<button class="hookUp demoBtn">Click Me!</button> <button class="hookUp demoBtn">Click Me!</button> <button class="hookUp demoBtn">Click Me!</button> <button class="hookUp demoBtn">Click Me!</button> <script> // Wait for the DOM to be ready before working with it require(["dojo/query", "dojo/domReady!"], function(query) { query(".hookUp").on("click", function(){ alert("This button is hooked up!"); }); }); </script>
on方法为query返回的每一个节点绑定事件。
总结
正如你所看到的,操做DOM的节点是至关的容易。使用query,咱们能够既快速又方便地获取到那些咱们想要操做的节点集。修改样式也一样也很容易。咱们展现了一个绑定点击事件到节点的简单实例,在下一篇文章中,咱们将深刻理解Dojo的事件机制。