操作dom时,可以使用dom.byId,缺陷是需要为每一个元素指定唯一ID,是一个可怕的和不切实际的工作。另一个解决方案,采用dojo/query模块。dojo/query使用我们熟悉的css选择器 检索一系列的节点。包括对先进的CSS3 选择器的支持。
1、查询
css/demo.css文件
- body {
- margin: 0;
- padding: 2em;
- font-family: Lucida Sans,Lucida Grande,Arial !important;
- font-size: 13px !important;
- background: white;
- color: #333;
- }
- button {
- background-color: #E4F2FF;
- background-image: url("//dijit/themes/claro/form/images/buttonEnabled.png");
- background-position: center top;
- background-repeat: repeat-x;
- border: 1px solid #769DC0;
- padding: 2px 8px 4px;
- font-size:1em;
- }
- button:hover {
- background-color: #AFD9FF;
- color: #000000;
- }
- .add-borders ul {
- border: 1px solid red;
- padding: 2px;
- }
- .add-borders li {
- border: 1px solid blue;
- padding: 2px;
- }
- .add-borders a {
- border: 1px solid black;
- padding: 2px;
- }
- .bold {
- font-weight: bold;
- }
- .italic {
- font-style: italic;
- }
- .highlight {
- background-color: yellow;
- }
- .red {
- background-color: red;
- }
- .blue {
- background-color: blue;
- }
query.html文件:
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <Meta charset="UTF-8">
- <title>Using dojo/query</title>
- <link rel="stylesheet" href="css/demo.css">
- <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
- </head>
- <body>
- <button class="queryButton">#list</button>
- <button class="queryButton">.odd</button>
- <button class="queryButton">#list .odd</button>
- <button class="queryButton">a.odd</button>
- <button class="queryButton">li a</button>
- <button class="queryButton">li > a</button>
- <button class="queryButton">.italic > a</button>
- <div class="add-borders">
- <ul id="list" class="">
- <li class="odd">
- <div class="bold">
- <a class="odd">Odd</a>
- </div>
- </li>
- <li class="even">
- <div class="italic">
- <a class="even highlight">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 highlight">Odd</a>
- </div>
- </li>
- <li class="even">
- <a class="even">Even</a>
- </li>
- </ul>
- <ul id="list2">
- <li class="odd">Odd</li>
- </ul>
- </div>
- </body>
- </html>
事件:
- <script>
- require(["dojo/query","dojo/NodeList-dom","dojo/domReady!"],function(query){
- function executeSeletor(button){
- query(".highlight").removeClass("highlight");
- query(button.innerHTML.replace(">",">")).addClass("highlight");
- }
- query(".queryButton").on("click",function(e){
- //console.dir(e);
- executeSeletor(e.target);
- })
- var list = query("#list");
- console.dir(list);
- });
- </script>
使用ID查询:
- // require the query and domReady modules
- require(["dojo/query",function(query) {
- // retrieve an array of nodes with the ID "list"
- var list = query("#list")[0];
- })
"#"标示符告诉query方法去查找拥有此Id属性的节点,与dom.byId功能类似。需要记住的一件事是:query 总是返回一个数组。通过ID抓取节点非常的好,但是他用起来没有 dom.byId强大,但是query允许你使用类名称来选取节点,如果我们只想检索拥有 "odd" 类名称的节点。
- // retrieve an array of nodes with the class name "odd"
- var odds = query(".odd");
使用"."标示符我们告诉query去查找拥有此类名称属性的节点,将返回一个拥有4个<li>和3个<a>的数组。
2、限制你的查询
- // 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节点被指定为第二个参数,将限定query到此节点及其子节点上。如果你的DOM相当的小省略第二个参数是可接受的,如果一个页面很大的DOM结构,使用第二个参数限定你 的查询将更好,通过具体的节点范围询将比在整个文档中查询更加的高效,能提供更好的用户体验。
3、更高级的选择
前面的查询包含了<li>和<a>标签,如果我们只想查询<a>标签要怎么办呢,你可以将一个标签名字和一个类名字合并:
- var oddA = query("a.odd");
选择li下所有a元素:
- // Retrieve an array of any a element that has an
- // li as its ancestor.
- var allA = query("li a");
选择li下第一个子元素为a的所有a元素:
- // Retrieve an array of any a element that has an
- // li as its direct parent.
- var someA = query("li > a");
4、节点列表
前面提到query返回符合选择器的一个节点数组,这是一个特殊的数组叫做dojo/NodeList。
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <Meta charset="UTF-8">
- <title>Using dojo/query</title>
- <link rel="stylesheet" href="css/demo.css">
- <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
- <script>
- // Wait for the DOM to be ready before working with it
- require(["dojo/query","dojo/dom-class",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");
- });
- });
- </script>
- </head>
- <body>
- <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>
- </body>
- </html>
传递给foreach的函数是一个回调函数,被数组中的每个条目所调用,该回调函数包含三个参数:当前的节点,节点的索引,需要迭代的节点列表。
对大多数开发者,第三个参数可以忽略。如果数组未被保存在一个容易访问的变量中,使用第三个参数访问数组中的其他元素很有用的。
dojo/NodeList-dom 提供便利的方法来搭配dojo中的各种dom方法,上面的示例等效于:
- <script>
- require(["dojo/query",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");
- });
- </script>
支持链式访问:
样例一:
- // Remove "red" from and add "blue" to the className
- // of each node matching the selector ".odd"
- query(".odd").removeClass("red").addClass("blue");
样例二:
- // 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");
5、事件
节点列表提供的另一个便利方法是: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",function(query) {
- query(".hookUp").on("click",function(){
- alert("This button is hooked up!");
- });
- });
- </script>