原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/using_query/
?
在本教程中,我们将学习dojo/query模块的搜索功能。
?
开始
在操作DOM对象中,一项重要的功能就是对节点的快速有效的检索。我们可以使用dom.byId来搜索一个指定ID的节点。但对于多个节点的操作这种做法显的有点繁琐,因为你要为每个你想要操作的节点都给定唯一的ID值。幸好,有另一种解决方案,使用dojo/query,这个模块使用类似于CSS搜索方式来搜索节点的列表。
?
搜索
为了展示如果使用搜索的,我们来使用一个经常能遇到的HTML页面内容。
?
<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来操作。我们就从这个例子开始
?
// 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的节点但和dojo.byId比起来好像没什么更特殊的。但是,query是可以使用class名称来进行搜索的
?
// retrieve an array of nodes with the class name "odd" var odds = query(".odd");
?
?使用"."前缀就是让query去搜索class的值为指定值的节点集合。在上面的例子中,会返回4个<li>元素和3个<a>元素
?
通过条件搜索
你会注意到,上面的代码会搜索出DOM中所有的符合条件的节点。如果我现在只想要在第一个list中的节点,那么会有两种方法来解决。
?
// 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"));
?
?上面的两咱方法的返回值都是一样的。但是第一种方法是在搜索出的所有结果中来选出符合条件的集合。第二种方法是,只在一个范围中去搜索结果集合。
?
当query方法没有传入第二个参数时,它就会搜索整合文档来查找结果。当有第二个参数时,就会在第二个参数指定的范围内去查询结果。
?
如果你的文档很小,就像我们的例子一样,可以忽略第二个参数。但是如果你的页面有着很大的DOM结构,那么建设你使用带有第二个参数的query方法,它会更快更有效。
?
高级搜索
上面的示例中,我们搜索出了含有<li>和<a>元素的结果,但如果我们只想要<a>元素的class名为odd的结果将怎么办?使用下面的方法。
?
var oddA = query("a.odd");
?
使用节点和class名的混合查法,这会非常的有效
还有一种搜索的方法,但是这种方法不是在所有位置的样式中都有效,就是使用">"
?
// 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 ancestor. var someA = query("li > a");
?
?运行示例
?
6个allA将全部使用<a>元素,但someA只有2个使用<a>元素。
?
节点链
上面已经说过,使用query返回的是一个集合,这个集合又被叫做NodeList,集合中的节点他们的方法可以相与的链接。我们来准备新的示例
?
<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>
?
?NodeList有着一些非常有用的方法,比如有一个方法叫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有点像回调函数,每个回调的function里都有下面的几个参数。当前的节点,节点的序号,和NodeList,对于大多数开发都来说,第三个参数是可以忽略的,但有时它也会很有用。
?
还有一些对于NodeList有用的方法,如map,filter,every,some.除了every和some是返回boolean,其它每个方法都是返回一个NodeList,这方便于使用方法链。
?
在1.7版本中,把class和style的操作移动到了dojo/NodeList-dom,它提供了操作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
?
// Remove "red" from and add "blue" to the className // of each node matching the selector ".odd" query(".odd").removeClass("red").addClass("blue");
?
?在dojo/NodeList-dom中还有一些别的方法 style,toggleClass,replaceClass,place,empty每个方法也是都返回NodeList
?
// Change the font color to "white" and add "italic" to // the className of each node matching the selector ".even" query(".even").style("color", "white").addClass("italic");
?
?运行示例
?
事件
NodeList还有一个便利的方法,叫on,它用于链接DOM和事件。这样就不用使用大量的代码来连接事件和节点了。事件将在后续的教程学习
?
<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>
?运行示例
?