• 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代码包含了一个我们在页面中经常见到的链接列表。代码如下:

     1 <ul id="list">
     2     <li class="odd">
     3         <div class="bold">
     4             <a class="odd">Odd</a>
     5         </div>
     6     </li>
     7     <li class="even">
     8         <div class="italic">
     9             <a class="even">Even</a>
    10         </div>
    11     </li>
    12     <li class="odd">
    13         <a class="odd">Odd</a>
    14     </li>
    15     <li class="even">
    16         <div class="bold">
    17             <a class="even">Even</a>
    18         </div>
    19     </li>
    20     <li class="odd">
    21         <div class="italic">
    22             <a class="odd">Odd</a>
    23         </div>
    24     </li>
    25     <li class="even">
    26         <a class="even">Even</a>
    27     </li>
    28 </ul>
    29 
    30 <ul id="list2">
    31     <li class="odd">Odd</li>
    32 </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函数似乎用处不大,但我们看下下面的例子:

    1 // require the query, dom, and domReady modules
    2 require(["dojo/query", "dojo/dom", "dojo/domReady!"], function (query, dom) {
    3     // retrieve an array of nodes with the ID "list"
    4     var list = query("#list")[0];
    5 })

    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的节点列表,代码如下:

    1 // retrieve an array of nodes with the class name "odd"
    2 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的节点呢?我们有两种方法解决这个问题:

    1 // retrieve an array of nodes with the class name "odd"
    2 // from the first list using a selector
    3 var odds1 = query("#list .odd");
    4 
    5 // retrieve an array of nodes with the class name "odd"
    6 // from the first list using a DOM node
    7 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结合在一起检索:

    1 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:

    1 // Retrieve an array of any a element that has an
    2 // li as its ancestor.
    3 var allA = query("li a");
    4 // Retrieve an array of any a element that has an
    5 // li as its direct parent.
    6 var someA = query("li > a");

    View Demo

    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模块中,该模块包含了对节点的一些相关操作。下面让我们看下你可以在你的应用中使用到的一些方法。例子如下:

    1 <div id="list">
    2     <div class="odd">One</div>
    3     <div class="even">Two</div>
    4     <div class="odd">Three</div>
    5     <div class="even">Four</div>
    6     <div class="odd">Five</div>
    7     <div class="even">Six</div>
    8 </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,该方法可以循环集合,在循环中获取每个节点的引用。

     1 // Wait for the DOM to be ready before working with it
     2 require(["dojo/query", "dojo/dom-class", "dojo/domReady!"],
     3     function(query, domClass) {
     4 
     5         query(".odd").forEach(function(node, index, nodelist){
     6             // for each node in the array returned by query,
     7             // execute the following code
     8             domClass.add(node, "red");
     9         });
    10 
    11 });

    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 NodeLists 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节点更便捷的方法:

    1 require(["dojo/query", "dojo/NodeList-dom", "dojo/domReady!"], function(query) {
    2     // Add "red" to the className of each node matching
    3     // the selector ".odd"
    4     query(".odd").addClass("red");
    5     // Add "blue" to the className of each node matching
    6     // the selector ".even"
    7     query(".even").addClass("blue");
    8 });

    The DOM methods are executed for each node in the NodeList and return a NodeList for easy chaining:

    函数会循环DOM的每个节点,并得到NOdeList返回给函数调用者。

    1 // Remove "red" from and add "blue" to the className
    2 // of each node matching the selector ".odd"
    3 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。

    1 // Change the font color to "white" and add "italic" to
    2 // the className of each node matching the selector ".even"
    3 query(".even").style("color", "white").addClass("italic");

    View Demo

    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.

     1 <button class="hookUp demoBtn">Click Me!</button>
     2 <button class="hookUp demoBtn">Click Me!</button>
     3 <button class="hookUp demoBtn">Click Me!</button>
     4 <button class="hookUp demoBtn">Click Me!</button>
     5 <script>
     6     // Wait for the DOM to be ready before working with it
     7     require(["dojo/query", "dojo/domReady!"], function(query) {
     8         query(".hookUp").on("click", function(){
     9             alert("This button is hooked up!");
    10         });
    11     });
    12 </script>

    View Demo

    该方法为每个查询的结果节点都绑定了点击事件。

    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如何定义事件的。

  • 相关阅读:
    Docker入门
    15个Docker基本命令及用法
    Docker系列
    docker
    Docker 常用命令
    查看用户列表在Linux
    Spring boot Mybatis
    CountDownLatch和CyclicBarrier 专题
    Spring Boot MyBatis 连接数据库
    Spring Boot MyBatis 通用Mapper插件集成 good
  • 原文地址:https://www.cnblogs.com/mytudousi/p/6211294.html
Copyright © 2020-2023  润新知