如何使用dojo.query 进行DOM查询和批量操作
前端之家收集整理的这篇文章主要介绍了
如何使用dojo.query 进行DOM查询和批量操作,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
入门
@H_
403_4@对DOM编程的一个关键要素是能够
快速高效的
获取到你所要使用的节点。之前我们曾经介绍过使用dojo.byId来查找DOM节点的
方法。但是,这种
方法的局限性也很明显。你很难为
页面上每个节点都起一个唯一的ID;而且通过dojo.byId查找得到的总是单个节点,当你需要对一组节点做同样的动作时,dojo.byId 就无能为力了。
解决这些局限的
方法就是我们今天将要介绍的:dojo.query 。 dojo.query
方法使用了类似CSS
查询的方式来
获取一组节点,在新版的dojo当中,它甚至已经完全可以
支持高级的CSS3 选择器(selector )了。
@H_
403_4@为了演示一些最常用的DOM
查询示例,我们假设了如下的一个HTML
页面片段. (这是常见的包含一系列
链接的HTML片段)
- <ulid="list">
- <liclass="odd">
- <divclass="bold">
- <aclass="odd">Odd</a>
- </div>
- </li>
- <liclass="even">
- <divclass="italic">
- <aclass="even">Even</a>
- </div>
- </li>
- <aclass="odd">Odd</a>
- <divclass="bold">
- <divclass="italic">
- <aclass="even">Even</a>
- </ul>
-
- <ulid="list2">
- <liclass="odd">Odd<li>
- </ul>
@H_
403_4@针对上述的HTML片段,能想到的第一个操作通常是如何
获取到整个列表的一个句柄. 当然你可以用dojo.byId,但dojo.query 也可以达到同样目的. 虽然初看起来,你会觉得在这里dojo.query 不是那么方便,但结合后面的例子你就会发现它的好处。
view plain
//获取所有包含节点ID为"list"节点的数组
- varlist=dojo.query("#list")[0];
@H_
403_4@通过在参数中加入"#",我们告诉dojo.query 去查找节点的"ID"
属性。这是从CSS操作中借鉴来的语法。 需要注意的是dojo.query 的返回值永远是一个数组。 在这个例子中,因为只有一个ID叫"list" 的节点,所以我们直接取出了该数组的第一个元素。
@H_
403_4@上面我们看到了如何通过ID来
获取节点,dojo.query 可不是只有这么点能力。它还
支持通过class name来选择节点。假设我们希望能够
获取所有class name等于"odd" 的节点:
//retrieveanarrayofnodeswiththeclassname"odd"
varodds=dojo.query(".odd");
@H_
403_4@通过在参数中加入".",我们告诉dojo.query 现在是要匹配节点的className
属性,这也是借鉴了CSS的语法。在这个例子中,dojo.query 将会返回包含4个<li> 节点和3个<a>节点 的数组。
限定查询条件的作用域
@H_
403_4@你可能已经发现了,在上一个例子中的得到odds数组同时包含了来自两个列表的节点。 假设我们只需要
获取第一个列表中的odd节点呢? 有两种
方法
//使用选择器来限定查询的作用域
varodds1=dojo.query("#list.odd");
//使用第二个参数来限定查询的作用域
varodds2=dojo.query(".odd",dojo.byId("list"));
@H_
403_4@这两种
方法返回的都是相同的元素, 第一个
方法使用了选择器的语法,限制了
查询的结果在ID为list的元素内,而第二个
方法则将一个节点作为限定
查询参数传入query。
@H_
403_4@当dojo.query
方法不包含第二个参数时,它会
搜索整个DOM树结构,遍历<HTML>
标签中包含的每个节点。 如果该
方法调用时包含了一个DOM节点作为第二参数,这个节点就是
查询的作用域,
查询的结果一定是该节点或其子节点。
@H_
403_4@如果你的
页面的DOM树结构比较小,比如像我们这里使用的列表的例子,那么省略第二参数的做法是可以的,也不会过分影响效率。但是如果
页面很复杂,那么强烈建议你在使用dojo.query是明确指定第二参数来限定
查询的作用域.这会大大减少无谓的对整个
页面进行
搜索操作从而提升速度和
性能。
@H_
403_4@为了方便,在接下来的例子中,我们都会省略第二个参数,不过请你一定要记住:在真实应用中你应该尽可能的制定作用域来让
查询操作
快速高效。
更多高级的查询
@H_
403_4@前面的例子中,我们
查询得到的结果集包含了<li> 节点和<a> 节点两种,如果我们只想要其中的<a> 节点该如何做呢? 在dojo.query
查询时我们可以将
标签名和class 名组合作为
查询条件:
varoddA=dojo.query("a.odd");
@H_
403_4@dojo.query 还
支持另一种选择器, ">". CSS中使用">" 并不被所有浏览器
支持,但是在dojo.query中却可以通用.
@H_
403_4@使用这个选择器,
查询会
//获取任意一个有li节点作为其父节点的a节点
varallA=dojo.query("lia");
//获取任意一个有li节点作为其直接父节点的a节点
varsomeA=dojo.query("li>a");
@H_
403_4@
查看示例
@H_
403_4@在我们的例子中,allA会
查询出6个<a>节点,而someA只会包含2个<a>。 在">" 两侧可以使用任意的其他选择器,
包括class 选择器。这里我们只是介绍了几种最常用的选择器,但dojo.query 是完全兼容CSS3的,还能够
支持很多
其他的选择器.你可以自己进一步学习掌握.
NodeList(操作dojo.query返回的结果集)
@H_
403_4@前文提到,dojo.query 返回的是匹配
查询结果的所有节点构成的数组;这个数组实际上是一个特殊的数组对象称为dojo.NodeList, 该数组对象内建了一系列可以方便操作其中节点的
方法.
@H_
403_4@下面我们来看一下其中常用的一些
方法, 在这个章节我们会使用下面的一个
HTML代码片段:
<divid="list">
<divclass="odd">One</div>
<divclass="even">Two</div>
<divclass="odd">Three</div>
<divclass="even">Four</div>
<divclass="odd">Five</div>
<divclass="even">Six</div>
</div>
@H_
403_4@dojo.NodeList 内建了一些Dojo 数组辅助
方法. 例如forEach,它可以对数组中的每个元素执行一个
函数:
dojo.query(".odd").forEach(function(node,index,nodelist){
//针对query返回的数组中的每个节点,执行本方法
dojo.addClass(node,"red");
});
@H_
403_4@被传入forEach的
函数是一个回调
函数,该回调
函数支持3个参数: 当前正在操作的节点,该节点在数组中的位置序号,以及当前正在遍历的结果集(是一个dojo.NodeList 对象)
@H_
403_4@对大多数开发者而言,第三个参数一般用不到,仅当你在回调
函数中需要去操作结果集中的其他节点时需要用到这个参数. forEach
方法还可以接受第二个参数,作为回调
函数调用的作用域(Scope)
@H_
403_4@dojo.NodeList中内建的其他数组辅助
方法还
包括: map,filter,every,和 some. 大多
方法都返回一个dojo.NodeList 对象,因此很容易串联使用. some 和every是例外,它们返回值是布尔值(boolean)
@H_
403_4@dojo.NodeList还内建了一些方面DOM操作的
方法, 上一个例子还可以进一步简化为
//向所有符合".odd"查询条件的节点加入className属性"red"
dojo.query(".odd").addClass("red");
//向所有符合".even"查询条件的节点加入className属性"blue"
dojo.query(".even").addClass("blue");
@H_
403_4@这些DOM操作
方法会在dojo.NodeList中每个节点上执行,同事返回值仍然是一个dojo.NodeList,可以串联使用.例如
//所有符合".odd"条件的节点上删掉red属性而添加blue属性
dojo.query(".odd").removeClass("red").addClass("blue");
@H_
403_4@其他dojo.NodeList 的DOM操作
方法还
包括: style,toggleClass,replaceClass,place 和empty. 所有这些
方法都会返回dojo.NodeList,供串联使用.
//把所有符合".even"条件的节点的字体颜色变为"while",并在节点上添加className"italic"
dojo.query(".even").style("color","white").addClass("italic");
事件
@H_
403_4@dojo.NodeList 上提供的另一重要
方法是connect,用来连接DOM事件. 关于如何在Dojo中处理DOM事件会在下一个讲义中详细讨论,我们这里要解释一下如何使用dojo.NodeList的connect
方法.
@H_
403_4@特别要注意的是,虽然在dojo.NodeList上使用connect很方便,但是并不适用于dojo.NodeList 包含大量节点的情形,这种情况下应该使用一种称为事件代理(event delegation)的技巧.关于这一技巧我们会在未来的讲义中探讨.
<buttonclass="hookUpdemoBtn">ClickMe!</button>
<buttonclass="hookUpToodemoBtn">ClickMe!</button>
<buttonclass="hookUpToodemoBtn">ClickMe!</button>
<buttonclass="hookUpdemoBtn">ClickMe!</button>
<mce:scripttype="text/javascript"><!--
//等待浏览器中DOM树完全加载完毕再执行操作
dojo.ready(function(){
//连接到所有符合".hookUp"条件的节点的"onclick"事件
dojo.query(".hookUp").connect("onclick",function(){
alert("Thisbuttonishookedup!");
});
//另一种连接事件的语法
dojo.query(".hookUpToo").onclick(function(){
alert("Thisbuttonishookeduptoo!");
});
//--></mce:script>
@H_
403_4@上面的例子中我们演示了两种将dojo.NodeList连接到DOM事件的
方法:
@H_
403_4@通用的connect
方法, 参数中指定事件
名称和回调
函数
@H_
403_4@使用一系列预定义的onXXXX
方法,
完整的方法列表可以在参考手册中查找
@H_
403_4@第二种做法更加简洁一些,但是内建的onXXX
方法仅包含了标准的DOM事件, 对于一些非标准事件例如 DOMAttrModified, 则只能使用第一种
方法.
小结
@H_
403_4@利用dojo.query 以及dojo.NodeList,对批量的DOM节点进行操作是很简单的:
@H_
403_4@使用dojo.query
查询到你所需要操作的节点,再使用dojo.NodeList的内建
方法对这些节点进行
修改操作. 下面一章我们将会进一步介绍如何使用Dojo向
页面中
添加互动,如何使用dojo中的事件机制。