Using dojo/query(翻译)
In this tutorial, we will learn about DOM querying and how the dojo/query
module allows you to easily select nodes and work with them.
在本教程中,我们将学习DOM查询,并且使用dojo/query模块,更容易的选择几点,并完成相关操纵。
Getting Started 开始
When working with the DOM, it's important to be able to retrieve nodes quickly and efficiently. We've covered one option: dom.byId
. However, coming up with unique IDs for every interesting node in your application can be a daunting and impractical task. It would also be inefficient to find and operate on multiple nodes by ID alone. Thankfully, there is another solution: dojo/query
. The dojo/query
module uses familiar CSS queries (which you use in your stylesheets) to retrieve a list of nodes, including support for advanced CSS3 selectors!
当操作DOM时,如何有效快速的获取节点是非常重要的。之前,我们已经学习了使用dom.byId函数选择某一个节点。但你不可能为你应用中每个节点都定义一个有意义的ID。当我们想要获取多个节点的时候,通过ID一个一个的获取也是很麻烦的。幸好,我们有另外一个解决方案:dojo/query模块。该模块使用了类似于CSS选择器的方式,可以一次获取符合条件的节点列表。
Queries 查询
To demonstrate some of the most common queries, we'll be using the following HTML, which might be something you would see if you were developing a list of links for a website:
为了说明问题,我们使用下面的html来说明如何在页面中检索DOM节点。下面的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>
The first thing you might want to do is get a handle for the entire list. As we've seen before, you can use dom.byId
, but you can also use query
. At first glance, this approach isn't that useful, but we'll be building from this example:
你想做的第一件事,可能是想得到整个列表的引用。正如我们之前讨论的,你可以使用dom.byId函数,但你与可以使用query函数。咋一看,你可能会觉得query函数似乎用处不大,但我们看下下面的例子:
// require the query, dom, and domReady modules
require(["dojo/query", "dojo/dom", "dojo/domReady!"], function (query, dom) {
// retrieve an array of nodes with the ID "list"
var list = query("#list")[0];
})
By prepending an identifier with "#", we are telling query
to look for nodes with that ID property. This convention should be familiar from CSS. One thing to note: query
always returns an array. We'll talk more about this array later, but since there is only one (and should only be one) node with the ID "list", we fetch that element out of the array.
通过#标识符,我们可以告诉查询器去查询ID等于"list"的节点。这种用法和CSS中的用法很像。有一点需要我们注意:Query函数永远返回一个集合。关于返回的集合,我们后面再详细的解释。但在我们上面定义的代码中,只有一个ID是list的节点。我们可以把节点对象从集合中取出来。
Fetching nodes by ID is nice, but it's no more powerful than using dom.byId
. However, query
allows you to select nodes by class names as well. Let's say we wanted to retrieve only the nodes with the "odd" class name:
我们通过dojo/query获取了一个ID等于list的节点对象,但这并没有使用dom.byId函数多做什么事情,反而使用起来比较麻烦。但query函数的作用远不及此。你也可以使用节点的classname作为关键字来检索。下面,我们想获取class name为odd的节点列表,代码如下:
// retrieve an array of nodes with the class name "odd"
var odds = query(".odd");
By prepending an identifier with ".", we are telling query
to look for nodes with that identifier in their className
property. Again, this is exactly like CSS. Using our example markup, query
will return an array containing 4 <li>
's and 3 <a>
's.
通过.标识符,我们告诉query函数,检索classname=odd的节点,这和CSS中的使用方法也是一样的。在这个例子中,我们的query函数将返回4个<li>节点和3个<a>节点。
Restricting your query 查询约束
You might have noticed that odds
in the prior example contains nodes from both lists that are in the DOM. Let's say we only wanted the odd nodes from the first list. There are two ways to do this:
你可能注意到了,我们在检索classname=odd的时候,是把整个DOM树中的所有classname=odd的节点都获取到了。但如果我们只是想从第一个列表中获取classname=odd的节点呢?我们有两种方法解决这个问题:
// 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", dom.byId("list"));
Both arrays contain the same elements, but through different methods: the first by using selector syntax and letting the query engine limit the results from all of the DOM; the second by limiting the scope of the query engine to a specific DOM node.
这两个函数返回的集合都是一样的,只是使用了两种不同的方法。第一个是先使用查询器,限制要查找的节点,然后再从该节点中查询我们需要的odd节点集合。第二个是先查询odd,然后再把范围缩减到一个指定的节点下。
When query
is executed without a second parameter, it will search the entire DOM structure, going through effectively every node under . When a DOM node is specified as the second argument, it restricts the query to that node and its children.
当query函数没有第二个参数时,query会检索整个DOM树结构,一直到每个叶子节点。当一个DOM节点作为第二个参数传递给Query函数,这就会限制检索只能在该节点以及该节点下的子节点中进行。
If your DOM is relatively small, such as in our example, omitting the second argument is acceptable. However, for pages with a larger DOM structure, it's preferable to restrict your query
calls with the second argument. It makes for more specific selections that execute more quickly than searches across the full document.
如果像我们上面的例子中,DOM树节点较少,我们可以省略第二个参数,直接检索。但如果是一个页面具有较大的DOM结构树,那么建议你还是根据实际需要,设置第二个参数,对查询器进行限定。
For the rest of our examples here, we will be omitting the second scoping argument, but keep the previous paragraph in mind when using query
yourself — keeping your searches quick and lean results in faster code and better user experience.
作为例子,我们没有过多考虑第二个参数,但我们上面关于第二个参数的一些讨论是值得我们在实际项目中认真考虑的。这样会加快节点检索速度,给用户更好的体验。
More advanced selections 高级选择器
Our previous query results contained a mix of <li>
's and <a>
's, but what if we're only concerned about the <a>
's? You can combine tag names with class names:
在上面的例子中,我们得到的结果包含了<li>和<a>节点,但我们如何能够让返回的结果只包含<a>节点呢?你可以把Tag Name和Class Name结合在一起检索:
var oddA = query("a.odd");
Instead of separating identifiers (which shows hierarchy), you can combine identifiers to target nodes more specifically; this includes combining class names, which has varying effects in stylesheets cross-browser, but works using query
.
你可以把想获得的目标节点的tagName放在标识符的前面,就像上面代码:a.odd。但这种方式在不同的浏览器下,可能会产生不同的结果。
Another selector that works in query
across browsers, but isn't supported everywhere in stylesheets, is ">". This will look only immediately below the first selector for the second. For instance:
// 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");
allA
will contain a total of 6 <a>
's, whereas someA
will only contain 2 <a>
's. Any selector can be on either side of ">", including class selectors. We've only covered a few of the more common selectors here, but query
is fully CSS3 compliant and accepts many more selectors which you can experiment with on your own.
上面的代码中,allA变量包含了全部的6个<a>节点,而someA只包含了两个<a>节点。任何选择器都可以放在符号>号的两边。我们在这里只是介绍了几个查询器的用法,更多的用法可以参考在CSS3中是如何使用的。
NodeList 节点列表
As mentioned before, query
returns an array of nodes that match the selector; this array is actually a dojo/NodeList
and has methods for interacting with the nodes contained in it. The demo for the previous examples used a couple of these methods, but let's take a look at some of the ones you'll most likely use in your applications. For this set of examples, we'll be using the following markup:
如前所述,查询器会返回匹配成功的节点集合。该集合就定义的dojo/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
has methods that match the Dojo array helper methods. One such method is forEach
, which will execute a function for each node in the array:
NodeList匹配了DOJO中集合的一些常用方法。一个重要的方法及时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");
}); });
The function passed to forEach
, also known as a callback, is called for each item in the array with the following arguments: the node it's currently on, the index of the node, and the NodeList
being iterated over. For most developers, the third argument can be ignored; however, in instances where the array isn't stored in a variable for easy access (such as in this example), the third argument can be useful for getting other items from the array. The forEach
method also accepts a second argument to specify what scope the callback should be called in.
通过forEach函数,可以循环集合中的每个对象,并获取对象,传递给主体代码块。forEach中的匿名函数中的三个参数的意义如下:
node:当前正循环到的节点对象。
index:当前循环到的索引值,也就是当前对象的索引值;
NodeList:就是我们循环的集合对象,query("odd")返回的对象。
对于大多数开发人员而言,第三个参数可以忽略掉。只是忽略掉之后,在循环函数中再想从列表中获取其他的节点对象,就不太方便了。要做当前节点和下一节点的对比,就会使用NodeList[Index +1]获取。
forEach函数除了接收用于循环的匿名函数外,也可以接受第二个参数(函数),该参数就会作为该循环的回调函数使用,每循环到一个节点,就会调用该函数。
Other array helper functions that are defined for NodeList
s are map
, filter
, every
, and some
. Each of these methods returns a NodeList
for easy chaining, except for every
and some
, which return a boolean.
其他的一个为NodeList定义的帮助函数包括map、filter、every和some。除了every和some函数返回bool类型的值外,其他函数都返回nodeList。
There are several extension modules that extend NodeLists
by adding extra methods to them. Class and style helper methods are in the dojo/NodeList-dom
module. dojo/NodeList-dom
provides convenience methods that match various DOM methods in Dojo, so the prior example could be simplified:
也有一些扩展模块同过插件的方式扩展了NodeLists的功能。Class和Style相关的帮助函数定义在dojo/NodeList-dom模块中。dojo/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");
});
The DOM methods are executed for each node in the NodeList
and return a NodeList
for easy chaining:
函数会循环DOM的每个节点,并得到NOdeList返回给函数调用者。
// Remove "red" from and add "blue" to the className
// of each node matching the selector ".odd"
query(".odd").removeClass("red").addClass("blue");
Other DOM methods that are defined by dojo/NodeList-dom
are style
, toggleClass
, replaceClass
, place
, and empty
. Each of these methods returns a NodeList
as well:
dojo/NodeList-dom
模块定义的其他函数包括style
, toggleClass
, replaceClass
, place
, and 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");
Events 事件
Another convenience method that NodeList
provides is on
for connecting to DOM events. Although DOM events are covered in the next tutorial, we'll cover the syntax of using NodeList
's on
method. It should also be noted that even though this is a convenient syntax, this approach should not be used with a NodeList
that contains a large number of nodes; instead, a technique called event delegation should be used in those instances, which is covered in the 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>
该方法为每个查询的结果节点都绑定了点击事件。
Conclusion 小结
As you can see, working with DOM nodes in bulk is fairly simple. Using query
, we can quickly and easily get a collection of the nodes that we want to work with. Being able to adjust styles and change classes in bulk is pretty handy, but where Dojo really starts to shine is adding interaction to a page. We've shown a simple example of how to handle a click event, but in the next tutorial, we'll dive deeper into handling events with Dojo.
正如你看到的,使用dojo/query后,我们批量操作节点变得更简单了,我们可以很容易获得我们需要的节点集合。之前,pie获取接待,改变class和style是很困哪的,但现在使用dojo可以很方便的实现。我们也通过了一个例子说明如何使用事件,但在下教程中,我们会更详细的了解dojo如何定义事件的。
Using dojo/query(翻译)的更多相关文章
- Events with Dojo(翻译)
In this tutorial, we will be exploring dojo/on and how Dojo makes it easy to connect to DOM events. ...
- dojo/query源码解析
dojo/query模块是dojo为开发者提供的dom查询接口.该模块的输出对象是一个使用css选择符来查询dom元素并返回NodeList对象的函数.同时,dojo/query模块也是一个插件,开发 ...
- dojo/dom dojo/domConstruct dojo/query
dom.byId require(["dojo/dom", "dojo/domReady!"], function(dom) { var one = dom.b ...
- dojo 六 使用query dojo/query
要使用query,就要引入dojo/query包.query可以根据Dom里节点的标签名.id名.class名来检索一个或多个节点.---------------------------------- ...
- dojo 学习笔记之dojo.query - query(id) 与query(class)的差别
考虑这个样例:动态创建一个页面的时候,用new listtem()生成多个listitem, 且每一个listitem中都生成一个按钮button. 假设想要给每一个按钮都绑定一个click事件,用d ...
- dojo.byId、dojo.query、dojo.attr
概述: dojo.byId(/*string*/id或/*DomNode*/node) 1.传入DOMNode返回传入的domNode; 2.传入id返回id为当前值的domNode dojo.que ...
- dojo query 基本用法
1. 常用的 dojo.query 用法 dojo.query("#header > h1") //ID 为 header 的元素的直接子节点中的 h3 元素 dojo. ...
- dojo 官方翻译 dojo/domReady 版本1.10
官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/domReady.html#dojo-domready dom加载完成后,执行. requi ...
- 使用dojoConfig配置dojo(翻译)
http://dojotoolkit.org/documentation/tutorials/1.10/dojo_config/index.html dojoConfig对象(原来是djConfig对 ...
随机推荐
- Maven学习笔记(1)之安装Maven
此笔记是学习Maven时自己摸索+各种百度而来,并非全部原创,望与各位一同学习,勿拍~勿拍~ 安装步骤 1.下载Maven的最新版本,地址:http://maven.apache.org/downlo ...
- SQL if exists database总是出现语法错误
SQL if exists总是出现语法错误.望高手纠正._百度知道 http://zhidao.baidu.com/link?url=7VyzcX0V1A3lhBQ1emNt2sTk7QGDuijOq ...
- 基于mongodb的java之增删改查(CRUD)
1,下载驱动https://github.com/mongodb/mongo-java-driver/downloads,导入工程java中 2,建立测试代码 import java.net.Unkn ...
- javscript创建Emitter
本文简单叙述下javascript是如何建立一个Emitter构造函数的. /** * 定义Emitter构造函数 */ function Emitter() { } /** * 添加监听事件 */ ...
- ASP.NET MVC过滤器中权限过滤器ValidateAntiForgeryToken的用法(Post-Only)
源参考:https://i.cnblogs.com/EditPosts.aspx?opt=1 用途:防止CSRF(跨网站请求伪造). 用法:在View->Form表单中:<%:Html.A ...
- This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.
-- :::] This application is modifying the autolayout engine from a background thread, which can lead ...
- 1.4 云计算的SPI服务模型
云计算是通过共享资源池的方式来提高资源利用率的.在云计算中,根据其资源池中资源的类别,可以把云计算的服务模型分为三种,即所谓的SPI 模型 应用程序 Software as a Service ( ...
- ubuntu安装opencv
ubuntu版本是12.04 ,opencv的版本是2.4.9 其实官网有教程的,http://docs.opencv.org/doc/tutorials/introduction/linux_ins ...
- ubuntu12.04静态ip设置问题
由于linux知识不是学的很深,所以仅代表我自己的设置成功总结. 第一步是设置/etc/network/interfaces 增加静态ip设置 auto eth0iface eth0 inet sta ...
- android 底层入门开发(二)
LED将为我闪烁:控制发光二极管 对于大多数Linux驱动来说,需要直接与硬件交互,本章主要介绍用Linux驱动来控制二极管的明暗,即通过Linux驱动发送数据控制开发板上LED灯的开关. 第一节介绍 ...