首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Dojo Query 详解(1)

Dojo Query 详解(1)

Dojo Query 简介在 Web 开发中,我们经常需要根据一定的条件查询并获取某些 HTML 元素的引用,然后对这些元素进行操作以改变它们的属性、外观等。在标准的 JavaScript 语言中,可以通过 document.getElementById, document.getElementsByTagName, document.getElementsByClassName 等函数对 DOM 树进行查询,然后遍历返回结果分别进行处理。在一些复杂的情况下,比如要查询 id 为“id1”的 div 元素下所有 class 为“class1”并且包含属性“att1”的元素,使用标准的 JavaScript 查询就显得力不从心,即使能够实现其代码也显得纷繁冗长。另一方面,在得到查询结果以后,假如要将所有返回的元素的 class 设置为“class2”,则需要遍历结果数组,一一进行设置。使用 JavaScript 标准的查询方式功能有限,使用复杂,而且当页面元素过多时还会导致性能降低。
Dojo Query 库提供了一种简洁而强大的查询语法,以及对返回结果简便的处理方式。Dojo Query 库的核心是一个 dojo.query 函数,该函数接收一个查询字符串,以及一个可选的 DOM 节点作为参数,返回一个 NodeList 对象。一方面我们可以通过 id,元素名称,属性,CSS 等及其组合设置精巧的查询字符串准确控制返回的结果,另一方面返回的 NodeList 对象提供了丰富的操作接口,对其调用的很多方法(如 addClass)都可以直接作用于所有的元素,并且支持链式调用。如下面的例子:
dojo.query("div.someClassName").style("backgroundColor","gray").forEach("item.disabled= true;");
首先在 DOM 根结点查询 class 为“someClassName”的 div 元素,对于返回的所有元素,将 style 属性“backgroundColor”设置为“gray”,然后将元素的“disabled”属性设置为“true”。使用 Dojo Query 能够精确地控制查询结果并方便地对所有结果进行操作,其使用非常简便,代码精炼,可读性强。本文后续章节将详细介绍查询语法及常见使用场景,以及 NodeList 对象的使用。
基于 Dojo Query 的查询当我们采用 Dojo Query 进行查询时,通常使用最多的就是根据 HTML 元素的 tag 名称,或是 class 以及 id 属性来进行查询。这也是我们在引用 CSS 元素进行选择时常用的几种方式。比如,假设我们想查询页面内所有的 <img> 标签,那么不妨可以这么写:
dojo.query("img");此处,img 即为标签名称,由于 Dojo Query 并不对大小写进行区分,故而形如 <IMG> 这样的 HTML 元素也会被包含在查询结果之中。上述语法的执行效果,等价于在 JavaScript 中调用 DOM API:document.getElementsByTagName("IMG")。
同样,根据 class 和 id 属性进行查询的语法,也很简单。例如,下面的例子实现的是在当前页面中查询 id 为 widget123 的元素:
dojo.query("#widget123");其执行效果,等价于调用 document.getElementById("widget123");,或者,利用 Dojo 提供的 API,则相当于 dojo.byId("widget123")。
针对 class 属性的查询同样的简单直观,例如,下面的例子是查找所有 class 名称为“offToSeeTheWij”的 HTML 元素:
dojo.query(".offToSeeTheWij");此处我们可以看到,同样的功能,如果用 DOM API 来实现,则将会变得非常冗长乏味:
清单 1 DOM API 查询 var list = [];  var nodes = document.getElementsByTagName("*");  for(var x = 0; x < nodes.length; x++){   if(nodes[x].className == "progressIndicator"){     list.push(nodes[x]);   }  }在上述代码中,我们需要对页面中的所有节点进行遍历,逐一判断其 className 属性是否满足匹配条件才行。通过这个典型的例子,我们可以清楚地看到,使用 Dojo Query 在 DOM 节点查询方面具有非常显著的优势。
事实上,使用 Dojo Query 不仅在表达查询条件的简洁性上会更具优势,相比于直接利用 DOM API 进行处理的方式,其执行速度也通常会更加的快。接下来读者便会看到,这一点尤其在我们需要查询相对复杂的页面节点关系时,会变得更为突出。
除了上述我们看到的,Dojo Query 提供了基本的依据 tag、class、id 进行查询的方式以外,它还提供了许多更为复杂的查询语法,而所有这些语法则都遵循于 CSS 规范。Dojo Query 的这一做法十分的明智,因为 CSS 是已经被大家所广泛使用和接受了的一种 Web 技术,其对 HTML 页面元素进行选择性修饰的方式,兼具语法简洁和功能强大的特点,目前所有的主流浏览器都对 CSS 有很好的支持。Dojo Query 沿用了 CSS 的语法,使得使用者无需学习一整套新的查询语法,便可以很好的掌握 Dojo Query 的使用,以完成各种复杂的查询功能。
目前,Dojo Query 支持许多常见的 CSS 选择器语法。例如,我们可以利用较为复杂的类选择器语法,实现对符合指定 class 属性的指定元素进行查询:
dojo.query("div.someClassName");又比如,我们可以将对各 tag 名称结合起来实现组合查询,下面完成的即是查询出所有的 h1,h2,h3 节点:
dojo.query("h1,h2,h3");除此以外,Dojo Query 还支持某些特殊的在 CSS 3 中定义的选择器。我们可以在查询条件中引用某些特殊的伪类选择符,比如可以利用 nth-child 来查询 tbody 节点下所有奇数序号的子元素:
dojo.query("tbody tr:nth-child(odd)");利用 first-child 来查询任意节点下的首个 p 子元素:
dojo.query("p:first-child");还可以利用诸如“^=”、“$=”、“*=”这样的属性选择器,实现匹配特定字符串条件的查询。例如,下列代码就是分别用来查询 name 属性的取值以“item”打头,以“item”结尾,和包含“item”字样的元素的:
清单 2 使用属性选择器 dojo.query("[name^=item]");  dojo.query("[name$=item]");  dojo.query("[name*=item]");上面我们看到的有关于 Dojo Query 的例子都只接受一个参数,它们实现的是在全局范围内,即整个页面范围内,对节点进行查询。Dojo Query 还支持局部范围内的相对查询。此时,除了查询表达式外,我们需要传入另一个参数,用以指示查询起始的根节点。该参数可以是一个字符串,Dojo Query 会将其视作元素的 id 值;或者我们也可以传入一个 DOM 节点。在下面的例子里,我们实现了在 thisForm 这个节点下进行查询的功能:
清单 3 局部范围内的相对查询 <html>  <head>  <script type="text/javascript" src="../js/dojo/dojo.js"></script>  <script type="text/javascript">      dojo.addOnLoad(function() {          console.debug(dojo.query("button").length);  // 输出"3"         console.debug(dojo.query("button", "thisForm").length);  // 输出”1”    });  </script>  </head>  <body>    <button id="b1" />    <button id="b2" />    <form id="thisForm" >       <button id="formB" />    </form>  </body>  </html>
返回列表