使用 dojo/query

在本篇文章中,咱們將瞭解DOM的查詢以及如何運用dojo/query這個模塊來輕鬆地選擇節點並操做他們。javascript

入門指南php

在操做DOM的過程當中,如何快速高效地檢索出DOM節點顯得至關重要。咱們在Dojo DOM Functions中已經熟悉了 dom.byId,然而,在應用程序裏找出每個感興趣的節點的惟一ID是項繁瑣且易錯的工做。而且僅靠ID的方式來選擇大量節點的效率可見是低下的。因此,這裏介紹另外一個解決方案:dojo/querydojo/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");

查看Demo

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-domdojo/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>

查看Deom

on方法爲query返回的每一個節點綁定事件。

總結

正如你所看到的,操做DOM的節點是至關的容易。使用query,咱們能夠既快速又方便地獲取到那些咱們想要操做的節點集。修改樣式也一樣也很容易。咱們展現了一個綁定點擊事件到節點的簡單實例,在下一篇文章中,咱們將深刻理解Dojo的事件機制。

相關文章
相關標籤/搜索