Dojo 1.6 最新官方教程: 如何使用dojo.query 進行DOM查詢和大量操作

來源:互聯網
上載者:User

 

在本講義中,我們將學到DOM的查詢,以及如何使用dojo.query來方便的尋找並操作DOM節點。

 

難度:初學者  適用的Dojo 版本: 1.6

作者: Bryan Forbes

譯者: feijia

原文串連: http://dojotoolkit.org/documentation/tutorials/1.6/using_query/

 

入門

 

對DOM編程的一個關鍵要素是能夠快速高效的擷取到你所要使用的節點。之前我們曾經介紹過使用dojo.byId來尋找DOM節點的方法。但是,這種方法的局限性也很明顯。你很難為頁面上每個節點都起一個唯一的ID;而且通過dojo.byId尋找得到的總是單個節點,當你需要對一組節點做同樣的動作時,dojo.byId 就無能為力了。解決這些局限的方法就是我們今天將要介紹的:dojo.query 。 dojo.query 方法使用了類似CSS查詢的方式來擷取一組節點,在新版的dojo當中,它甚至已經完全可以支援進階的CSS3 選取器(selector )了。

 

常用查詢

 

為了示範一些最常用的DOM查詢樣本,我們假設了如下的一個HTML頁面片段. (這是常見的包含一系列連結的HTML片段)

 <ul id="list"><br /> <li class="odd"><br /> <div class="bold"><br /> <a class="odd">Odd</a><br /> </div><br /> </li><br /> <li class="even"><br /> <div class="italic"><br /> <a class="even">Even</a><br /> </div><br /> </li><br /> <li class="odd"><br /> <a class="odd">Odd</a><br /> </li><br /> <li class="even"><br /> <div class="bold"><br /> <a class="even">Even</a><br /> </div><br /> </li><br /> <li class="odd"><br /> <div class="italic"><br /> <a class="odd">Odd</a><br /> </div><br /> </li><br /> <li class="even"><br /> <a class="even">Even</a><br /> </li><br /></ul></p><p><ul id="list2"><br /> <li class="odd">Odd<li><br /></ul>

 

 

針對上述的HTML片段,能想到的第一個操作通常是如何擷取到整個列表的一個控制代碼. 當然你可以用dojo.byId, 但dojo.query 也可以達到同樣目的. 雖然初看起來,你會覺得在這裡dojo.query 不是那麼方便,但結合後面的例子你就會發現它的好處。

 

// 擷取所有包含節點ID為"list"節點的數組<br />var list = dojo.query("#list")[0];<br />

 

通過在參數中加入"#", 我們告訴dojo.query 去尋找節點的"ID"屬性。這是從CSS操作中借鑒來的文法。 需要注意的是dojo.query 的傳回值永遠是一個數組。 在這個例子中,因為只有一個ID叫"list" 的節點,所以我們直接取出了該數組的第一個元素。 

 

上面我們看到了如何通過ID來擷取節點,dojo.query 可不是只有這麼點能力。它還支援通過class name來選擇節點。假設我們希望能夠擷取所有class name等於"odd" 的節點:

// retrieve an array of nodes with the class name "odd"<br />var odds = dojo.query(".odd");

 

 

通過在參數中加入".", 我們告訴dojo.query 現在是要匹配節點的className屬性, 這也是借鑒了CSS的文法。在這個例子中,dojo.query 將會返回包含4個<li> 節點和3個<a>節點 的數組。 

 

限定查詢條件的範圍

 

你可能已經發現了,在上一個例子中的得到odds數組同時包含了來自兩個列表的節點。 假設我們只需要擷取第一個列表中的odd節點呢? 有兩種方法

// 使用選取器來限定查詢的範圍<br />var odds1 = dojo.query("#list .odd");</p><p>// 使用第二個參數來限定查詢的範圍<br />var odds2 = dojo.query(".odd", dojo.byId("list"));

 

 

這兩種方法返回的都是相同的元素, 第一個方法使用了選取器的文法,限制了查詢的結果在ID為list的元素內,而第二個方法則將一個節點作為限定查詢參數傳入query。 

 

當dojo.query 方法不包含第二個參數時,它會搜尋整個DOM樹結構,遍曆<HTML>標籤中包含的每個節點。  如果該方法調用時包含了一個DOM節點作為第二參數,這個節點就是查詢的範圍, 查詢的結果一定是該節點或其子節點。

 

 

如果你的頁面的DOM樹結構比較小,比如像我們這裡使用的列表的例子,那麼省略第二參數的做法是可以的,也不會過分影響效率。但是如果頁面很複雜,那麼強烈建議你在使用dojo.query是明確指定第二參數來限定查詢的範圍.這會大大減少無謂的對整個頁面進行搜尋操作從而提升速度和效能。

 

為了方便,在接下來的例子中,我們都會省略第二個參數,不過請你一定要記住:在真實應用中你應該儘可能的制定範圍來讓查詢操作快速高效。

 

更多進階的查詢

 

前面的例子中,我們查詢得到的結果集包含了<li> 節點和<a> 節點兩種,如果我們只想要其中的<a> 節點該如何做呢?  在dojo.query 查詢時我們可以將 標籤名和class 名組合作為查詢條件:

 

var oddA = dojo.query("a.odd");

 

 

 

 

dojo.query 還支援另一種選取器, ">".  CSS中使用">" 並不被所有瀏覽器支援,但是在dojo.query中卻可以通用. 

使用這個選取器,查詢會

// 擷取任意一個有li節點作為其父節點的a節點<br />var allA = dojo.query("li a");<br />// 擷取任意一個有li節點作為其直接父節點的a節點<br />var someA = dojo.query("li > a");

 

查看樣本

在我們的例子中,allA會查詢出6個<a>節點,而someA只會包含2個<a>。 在">" 兩側可以使用任意的其他選取器,包括class 選取器。這裡我們只是介紹了幾種最常用的選取器,但dojo.query 是完全相容CSS3的,還能夠支援很多其他的選取器

.你可以自己進一步學習掌握.

NodeList(操作dojo.query返回的結果集)

 

前文提到,dojo.query 返回的是匹配查詢結果的所有節點構成的數組;這個數組實際上是一個特殊的數組對象稱為dojo.NodeList, 該數組對象內建了一系列可以方便操作其中節點的方法. 

 

下面我們來看一下其中常用的一些方法, 在這個章節我們會使用下面的一個HTML程式碼片段:

<div id="list"><br /> <div class="odd">One</div><br /> <div class="even">Two</div><br /> <div class="odd">Three</div><br /> <div class="even">Four</div><br /> <div class="odd">Five</div><br /> <div class="even">Six</div><br /></div>

 

 

dojo.NodeList 內建了一些Dojo 數組輔助方法. 例如forEach, 它可以對數組中的每個元素執行一個函數:

dojo.query(".odd").forEach(function(node, index, nodelist){<br /> // 針對query返回的數組中的每個節點,執行本方法<br /> dojo.addClass(node, "red");<br />});

 

 

被傳入forEach的函數是一個回呼函數,該回呼函數支援3個參數: 當前正在操作的節點,該節點在數組中的位置序號,以及當前正在遍曆的結果集(是一個dojo.NodeList 對象)

 

對大多數開發人員而言,第三個參數一般用不到, 僅當你在回呼函數中需要去操作結果集中的其他節點時需要用到這個參數. forEach方法還可以接受第二個參數,作為回呼函數調用的範圍(Scope)

 

dojo.NodeList中內建的其他數組輔助方法還包括: map,filter,every, 和 some. 大多方法都返回一個dojo.NodeList 對象,因此很容易串聯使用. some 和every是例外,它們傳回值是布爾值(boolean)

 

dojo.NodeList還內建了一些方面DOM操作的方法, 上一個例子還可以進一步簡化為

 

// 向所有符合".odd" 查詢條件的節點加入className屬性 "red"<br />dojo.query(".odd").addClass("red");<br />// 向所有符合".even" 查詢條件的節點加入className屬性 "blue"<br />dojo.query(".even").addClass("blue");

 

 

這些DOM操作方法會在dojo.NodeList中每個節點上執行,同事傳回值仍然是一個dojo.NodeList,可以串聯使用.例如

 

//所有符合".odd"條件的節點上刪掉red屬性而添加blue屬性<br />dojo.query(".odd").removeClass("red").addClass("blue");<br />

 

其他dojo.NodeList 的DOM操作方法還包括: style, toggleClass,replaceClass, place 和empty. 所有這些方法都會返回dojo.NodeList,供串聯使用.

 

 

//把所有符合".even"條件的節點的字型顏色變為"while",並在節點上添加className "italic"<br />dojo.query(".even").style("color", "white").addClass("italic");

 

 

事件

dojo.NodeList 上提供的另一重要方法是connect,用來串連DOM事件. 關於如何在Dojo中處理DOM事件會在下一個講義中詳細討論,我們這裡要解釋一下如何使用dojo.NodeList的connect方法.

 

特別要注意的是,雖然在dojo.NodeList上使用connect很方便,但是並不適用於dojo.NodeList 包含大量節點的情形, 這種情況下應該使用一種稱為事件代理(event delegation)的技巧.關於這一技巧我們會在未來的講義中探討.

 

<button class="hookUp demoBtn">Click Me!</button><br /><button class="hookUpToo demoBtn">Click Me!</button><br /><button class="hookUpToo demoBtn">Click Me!</button><br /><button class="hookUp demoBtn">Click Me!</button><br /><mce:script type="text/javascript"><!--<br /> // 等待瀏覽器中DOM樹完全載入完畢再執行操作<br /> dojo.ready(function(){<br /> // 串連到所有符合".hookUp"條件的節點的 "onclick" 事件<br /> dojo.query(".hookUp").connect("onclick", function(){<br /> alert("This button is hooked up!");<br /> });<br /> // 另一種串連事件的文法<br /> dojo.query(".hookUpToo").onclick(function(){<br /> alert("This button is hooked up too!");<br /> });<br /> });<br />// --></mce:script><br />

 

上面的例子中我們示範了兩種將dojo.NodeList串連到DOM事件的方法:

 

通用的connect 方法, 參數中指定事件名稱和回呼函數

使用一系列預定義的onXXXX 方法, 完整的方法列表

可以在參考手冊中尋找

 

第二種做法更加簡潔一些,但是內建的onXXX方法僅包含了標準的DOM事件, 對於一些非標準事件例如 DOMAttrModified, 則只能使用第一種方法.

 

小結

利用dojo.query 以及dojo.NodeList,對批量的DOM節點進行操作是很簡單的:

使用dojo.query 查詢到你所需要操作的節點,再使用dojo.NodeList的內建方法對這些節點進行修改操作. 下面一章我們將會進一步介紹如何使用Dojo向頁面中添加互動,如何使用dojo中的事件機制。 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.