在本篇文章中,咱們將瞭解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的事件機制。