当前位置 : 主页 > 网页制作 > Dojo >

Dojo 的文档操作基础二<9>

来源:互联网 收集:自由互联 发布时间:2021-06-15
通过该教程,我们将了解到Dojo中的DOM查询以及如何使用dojo/query 模块来选择节点和操作节点。 开始 当使用DOM工作, 最重要是的快速和有效的检索节点。 我们已经讲解了其中的一个do

通过该教程,我们将了解到Dojo中的DOM查询以及如何使用dojo/query 模块来选择节点和操作节点。

开始

当使用DOM工作, 最重要是的快速和有效的检索节点。 我们已经讲解了其中的一个dom.byId.  然而在你的应用程序中,给每一个想要操作的节点提供一个Id是不切实际的任务。 通过Id来查找和操作多个节点也是效率低下的。 幸运的是,dojo还有另外一个解决方案: dojo/query.  dojo/query 模块使用css选择器来检索一个节点列表, 它支持CSS3 选择器。

查询

为了演示最常见的几种查询, 我们将使用如下的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];
})

通过添加一个"#"标识符到 id 的前面, 我们可以告诉 query 通过节点的ID属性寻找节点,它是CSS 的一种约定。 需要注意的是: query 一直返回一个数组。 我们会在之后谈论这个数组, 但由于 仅有一个(而且应该仅有一个)ID为"list"的节点,所以我们需要从数组中取出元素。
通过id来获取节点非常好, 但这并不比使用dom.byId更强大。 可是, query 也允许你通过类名称来选择节点。 比如说,我们想要获得的"odd"类名的节点:
// retrieve an array of nodes with the class name "odd"
var odds = query(".odd");

通过添加"."前缀,我们告诉query查找节点的className属性。 查找我们例子中的HTML, query 将返回一个包含 4个<li> 元素和3 个<a>元素的数组。

限制性查找

你可能已经注意到, 以上的例子中会检索到两个list中的 odds. 假若我们仅想获得第一个list中的 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", document.getElementById("list"));

两个数组包含同样的元素, 但通过了不同的方法: 第一个是使用了选择器语法, 并让选择器引擎从所有的DOM里限定结果, 第二是以指定DOM节点来限定查询引擎的范围。
当没有给定第二个参数时, 它会搜索整个DOM结构, 仔细检查<html>下的每个节点。 当指定一个DOM节点为第二个参数时, 查询会只限定在指定的节点和它的子节点。
如果一个DOM非常的小, 比如我们例子, 忽略掉第二个参数还是可以接受。 对于一个DOM结构很大的页面,最好还是设置第二个参数, 相对于访问整个文档,更加快速。
在之后的例子中,我们都会省略掉第二个参数。 但你自己使用query时,请记住上面一段 - 设定第二个参数, 有利于更快的搜索和更好的用户体验。

更多高级选择


我们之前的查询结果混合了<li> 和 <a>, 但如果我们只想检索出<a>标签呢? 你可以混合 标签名和类名:
var oddA = query("a.odd");

另外一个选择器是 ">",例如:
// 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");
查看Demo
allA 变量包含 6 个 <a>标签, 然而  someA仅包含2个<a>标签。 ">"的任何一边可以放置任何选择器, 包括类选择器。 我们在这里仅讲部分常见的选择器,但query是完全支持 CSS3, 并接受 更多的选择器

节点列表(NodeList)

之前提到的, query返回一个匹配到的节点数组。 这个数组实际上是一个节点列表对像(dojo/NodeList),NodeList 包含与节点交互的方法。 上一个例子的Demo已经使用了几个这类方法, 但让我们看看在你的应用程序中最常用的几个, 我们使用以下的html标记:
<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 有的方法是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");
        });
 
});

这个函数被传递给 forEach, 也称为回调函数, 被每一个数组项调用,参数如下: 第一个为当前的节点, 第二个为节点在数组中的索引, 第三个为正在被遍历的数组. 大部分的开发者, 第三个参数会被忽略; 可是, 在一些例子中, 数组没有被赋值给相关的变量(比如在这个例子里), 那么第三个参数在获得数组中的其它项时非常有用。 forEach方法也接受第二个参数,指定什么范围内可以调用回调函数。
另外的数组辅助函数是给NodeLists 定义的,如map, filter,every和some, 除了every 和some返回一个布尔值外,其它的方法返回一个NodeList. 
这里还有几个扩展模块,它们在扩展了NodeLists模块,并添加额外的方法。 Class 和 Style 辅助方法在 dojo/NodeList-dom模块。 dojo/NodeList-dom提供的Dojo中各式各样的DOM方法(addClass,removeClass)。 所以之前的例子可以简单为:
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");
});

DOM 方法会被NodeList中的每一个节点执行, 返回一个为链式调用的NodeList( query(".odd").addClass("red").removeClass("red"), 这就是链式调用,链式调用的根本是执行完后需要返回一个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:
query(".even").style("color", "white").addClass("italic");

查看例子

事件


NodeList提供的另外一个遍历方法是on, 用来监听DOM事件。 虽然 DOM 事件会在下一个教程中讲解, 我们先讲解 NodeList的on 方法。 在这里应该注意,虽然on方法有方便的方法, 但最好不要用在一个包含大量节点的NodeList上。 而应该使用一用称为 事件委托的技术, 它会在 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>

查看Demo
on 方法会依附到每个Node上。

总结

像你看到的, 整批的处理DOM节点非常简单。 使用 query, 我们可以快速和容易的获得我们想用的节点。 我们已经通过一个简单例子知道如何处理一个点击事件, 但在 下一个教程中, 我们更深入的了解处理Dojo的事件 
网友评论