In this tutorial, you'll learn about how to use Dojo to manipulate the DOM in a simple, cross-browser way. Using basic DOM knowledge and only a few Dojo functions, you will be able to efficiently create, read, update and delete elements in the page on the fly.

在本教程中,你将学习如何使用DOJO控制DOM节点。使用一些基础的DOM知识和一些DOJO功能,你可以在页面上快捷有效的创建、读取、更新以及删除节点。

Getting Started 开始

As far as browser-based JavaScript is concerned, the Document Object Model (DOM) is the glass that we paint on to put content and user interface in front of our users. If we want to augment, replace or add to the HTML once loaded into the browser, JavaScript and the DOM is how it's done. Dojo aims to make working with the DOM easy and efficient by providing a handful of convenience functions that fill some awkward cross-browser incompatibilities and make common operations simpler and less verbose.

就基于javascript的浏览器而言,文档对象模型(DOM)是我们画在用户界面想展示给用户内容的反应。HTML加载到浏览器之后,如果我们还要修改这些元素,javascript操作DOM就可以做到。DOJO提供了操作DOM的功能,这些功能屏蔽了各不同浏览器之间的差异,并一种更加简单快捷的方式提供给开发者使用。

To explore those functions we will be manipulating a simple page containing an unordered list with five elements in it:

为了解释这些功能,我们将要创建一个简单页面,该页面包含了一个无序ListUI,该UI包含了5个节点元素。

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: DOM Functions</title>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true">
</script>
<script>
require(["dojo/domReady!"], function() { });
</script>
</head>
<body>
<ul id="list">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
</ul>
</body>
</html

The page already has the Dojo script tag, and you should recognize the require block. All code that manipulates the DOM must wait until the DOM is ready before it can be executed.

本页面已经包含引用DOJO的脚本标签快,并且你必须能识别出require函数。所有的主要处理代码都需要等DOM加载完毕后,能够被读取后才能够执行。

Retrieval 检索

First things first: We need to know how to get elements from the DOM, in order to work with them. The easiest way to do that is by using the dojo/dom resource's byId method. When you pass an ID to dom.byId, you will receive the DOM node object with that ID. If no matching node is found, a null value will be returned.

我们首先要做的事是:我们需要知道我们如何从DOM上获取节点进而操作他们。最简单的办法就是使用dojo/dom资源的byId函数。当你把节点的ID传递给该函数后,你就可以从DOM获取该ID节点的引用。如果没有该ID的节点元素,函数会返回NULL。

This is the equivalent of using document.getElementById, but with two advantages: it is shorter to type, and it works around some browsers' buggy implementations of getElementById. Another nice feature of dom.byId is that when it is passed a DOM node, it immediately returns that node. This helps to create APIs that take both strings and DOM nodes. Let's look at an example:

这个函数相当于使用了document.getElementById函数。但使用dojo/dom资源的byId函数有两点优势:代码更加简短,并且该函数解决了一些浏览器getElementById函数的一些bug。另外一个优秀的特性是当你传入一个DOM节点时,byId函数会立即返回该节点。这样就可以帮助你可以同时使用字符串和节点对象来创建你的API,下面我们看一个例子。

 // Require the DOM resource
require(["dojo/dom", "dojo/domReady!"], function(dom) { function setText(node, text){
node = dom.byId(node);
node.innerHTML = text;
} var one = dom.byId("one");
setText(one, "One has been set");
setText("two", "Two has been set as well"); });

View Demo

The setText function sets the text of a node, but since it passes the node argument to dom.byId it will take either a node ID as a string or a DOM node.

setText函数可以在节点上设置显示的文本。但我们使用的dom的byId函数,所以我们可以以字符串的形式传入节点ID,也可以直接传入DOM的节点对象。

Creation 创建

Another thing you will be doing often is creating elements. Dojo doesn't prevent you from using the native document.createElement method to create elements, but creating the element and setting all the necessary attributes and properties on it can be verbose. Furthermore, there are enough cross-browser quirks to attribute setting to make dojo/dom-construct's create method a more convenient and reliable option.

另一件你经常要做的操作就是创建元素。DOJO并不禁止你使用原生态的document.createElement方法创建元素,但这种创建元素的方法需要设置很多必须的属性,导致代码冗长。有着识别个浏览器差异的DOJO提供了dojo/dom-construct的create方法快捷方便的创建元素。

The arguments to domConstruct.create are as follows: node name as a string, properties of the node as an object, an optional parent or sibling node, and an optional position in reference to the parent or sibling node (which defaults to "last"). It returns the new DOM element node. Let's take a look at an example:

domConstruct.create函数需要的参数如下:节点的名称(字符串类型),节点对象的属性,父节点或者兄弟节点(可选参数),灾父节点或兄弟节点的相对位置(可选参数,默认值为last)。该函数会返回一个新的DOM节点元素。让我们看下下面的例子。

 require(["dojo/dom", "dojo/dom-construct", "dojo/domReady!"],
function(dom, domConstruct) { var list = dom.byId("list"),
three = dom.byId("three"); domConstruct.create("li", {
innerHTML: "Six"
}, list); domConstruct.create("li", {
innerHTML: "Seven",
className: "seven",
style: {
fontWeight: "bold"
}
}, list); domConstruct.create("li", {
innerHTML: "Three and a half"
}, three, "after");
});

View Demo

A simple list item is created with the content of "Six" and appended to the list. Next, another list item is created with the content of "Seven", its className property is set to "seven", it's styled so it has a bold font, and then appended to the list. Finally, a list item is created with the contents "Three and a half" and is inserted after the list item with the ID "three".

代码创建了一个内容为Six的列表元素,并添加到了List节点上。下面,另外一个内容为Seven的List item被创建,它的classname为“seven”,样式为字体加粗,然后添加到了列表中。最后一个内容为"Three and a half"的list item被创建,并且添加到ID为three的节点的后面。

When would you create elements explicitly like this, versus setting a container element's innerHTML property? If you already have your content as a string of HTML, setting the innerHTML property will always be faster. However, domConstruct.create comes into its own when you want to create elements but not immediately place them in the DOM, or when you want to insert or append a new element without disturbing the sibling nodes around it.

当你使用这种方式创建一个元素的时候,就可以同时设置容器元素的InnderHtml属性。如果你已经有了string类型的html内容,那么设置innerHtml属性会更快。然后,当你想创建一个元素的时候,使用domConstruct.create 不会立即呈现到DOM中,也无法以父节点和兄弟节点为参考添加或插入新的节点。

Placement 放置

If you already have a node and want to place that node, you will need to use domConstruct.place. The arguments are as follows: a DOM node or string ID of a node to place, a DOM node or string ID of a node to use as a reference, and an optional position as a string which defaults to "last" if not provided. This is very similar to what we saw in domConstruct.create and, in fact, domConstruct.create uses domConstruct.place under the hood. For our example, we have added a few buttons to the page:

如果你已经有了一个节点,想安置他的位置,你需要调用domConstruct.place函数。参数如下:

  • 需要放置的ODM节点对象或者其ID;
  • 需要使用的DOM节点ID或者节点对象引用;
  • 可选参数,位置。默认为last。

这比我们调用domConstruct.create函数简单一些,事实上,domConstruct.createdomConstruct.place的一个扩展。例如我们要网页面上加一些按钮。

 <button id="moveFirst">The first item</button>
<button id="moveBeforeTwo">Before Two</button>
<button id="moveAfterFour">After Four</button>
<button id="moveLast">The last item</button>

The example defines functions which move the third node around the list using domConstruct.place:

这个例子定义了一些函数,这些函数主要是在列表中,以多种方式在列表中移动第三个节点。

 require(["dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/domReady!"],
function(dom, domConstruct, on){ function moveFirst(){
var list = dom.byId("list"),
three = dom.byId("three"); domConstruct.place(three, list, "first");
} function moveBeforeTwo(){
var two = dom.byId("two"),
three = dom.byId("three"); domConstruct.place(three, two, "before");
} function moveAfterFour(){
var four = dom.byId("four"),
three = dom.byId("three"); domConstruct.place(three, four, "after");
} function moveLast(){
var list = dom.byId("list"),
three = dom.byId("three"); domConstruct.place(three, list);
} // Connect the buttons
on(dom.byId("moveFirst"), "click", moveFirst);
on(dom.byId("moveBeforeTwo"), "click", moveBeforeTwo);
on(dom.byId("moveAfterFour"), "click", moveAfterFour);
on(dom.byId("moveLast"), "click", moveLast);
});

View Demo

The possible values for the placement argument are "before", "after", "replace", "only", "first", and "last". Please see the reference guide for domConstruct.place for more details as to what each placement option does, though the names are decently intuitive.

placement参数可以取值"before", "after", "replace", "only", "first", and "last",每个参数的详细意义参考reference guide for domConstruct.place

In the simple case, domConstruct.place does little more than the native parentNode.appendChild(node) might do. Its value is in being able to easily specify position, whether it is in reference to a parent or sibling node - with one consistent API.

在这个简单的例子中domConstruct.place函数做了一些比原生态的parentNode.appendChild(node)更多的一些功能。无论是父节点还是同级节点,使用同一套API就可以比较简单的设置其位置。

Destruction 销毁

Most often you'll be creating nodes, but occasionally, you'll want to remove nodes as well. There are two ways to do this in Dojo: domConstruct.destroy which will destroy a node and all of its children, while domConstruct.empty will only destroy the children of a given node. Both take a DOM node or a string ID of a node as their only argument. We're going to add two more buttons to our page:

大多数据情况下,你都会创建节点,但有时候,你也会想移除节点。在dojo有两种方式可以移除节点:domConstruct.destroy函数,该函数可以销毁节点以及该节点下包含的内容。domConstruct.empty函数则只是销毁该节点下的子节点。在传参数的时候,ID字符串和节点对象都可以。我们在页面上再添加两个按钮:

 button id="destroyFirst">Destroy the first list item</button>
<button id="destroyAll">Destroy all list items</button>
 function destroyFirst(){
var list = dom.byId("list"),
items = list.getElementsByTagName("li"); if(items.length){
domConstruct.destroy(items[0]);
}
}
function destroyAll(){
domConstruct.empty("list");
} // Connect buttons to destroy elements
on(dom.byId("destroyFirst"), "click", destroyFirst);
on(dom.byId("destroyAll"), "click", destroyAll);

View Demo

The first button will destroy the first item in the list on each click. The second empties the list entirely.

每次点击第一个按钮,都会把list里面的节点元素的第一个删掉。点击第二个按钮,可以清空List中的节点列表。

Conclusion 总结

So far, we have a pretty comprehensive set of tools that we can use to do simple DOM manipulation, from creating nodes, to moving them about, to getting rid of them -- but they all work on only one node at a time. What if the nodes you want to work with don't have IDs? The next tutorial will cover dojo/query, which allows us to search for and work with nodes based on CSS selectors!

到目前为止,我们有一个非常全面的工具库来操作DOM,创建节点、移动几点或者移除节点---但这些功能都是在一个节点上操作。但如果你想操作的节点上没有ID标识怎么办?下一各教程就是介绍dojo/query模块,该模块可以允许我们通过CSS选择器选择多个节点对象。

DOJO DOM 功能的更多相关文章

  1. dojo/dom源码学习

    dojo/dom模块作为一个基础模块,最常用的就是byId方法.除此之外还有isDescendant和setSelectable方法. dom.byId(myId)方法:   各种前端类库都免不了与D ...

  2. dojo/dom dojo/domConstruct dojo/query

    dom.byId require(["dojo/dom", "dojo/domReady!"], function(dom) { var one = dom.b ...

  3. dojo 七 DOM dojo/dom

    官方教程:Dojo DOM Functions对dom的使用,需要引用包dojo/dom.1.获取节点,dom.byIdbyId中既可以传递一个字符串,也可以传递一个节点对象 require([&qu ...

  4. dojo/dom源码

    dojo/dom源码学习   dojo/dom模块作为一个基础模块,最常用的就是byId方法.除此之外还有isDescendant和setSelectable方法. dom.byId(myId)方法: ...

  5. 【JS】328- 8个你不知道的DOM功能

    最近一直在关注工具,从 React 和 npm-install-everything 中休息一下,看看一些原生的 DOM 和 Web API 的功能,他们可以在没有任何依赖库的浏览器中直接运行. 这篇 ...

  6. ztree : 增删改功能demo与自定义DOM功能demo的结合

    最近有个项目要用ztree,需要用ztree自带的功能(增删改),也需要自定义DOM的功能(置顶). ztree的demo里有增删改的demo,也有自定义DOM的demo,但没有两者结合的. 所以我把 ...

  7. 【Dojo 1.x】笔记3 等待DOM加载完成

    有的web页面总是得等DOM加载完成才能继续执行功能,例如,待页面DOM加载完成后,才能在DIV上进行渲染图形. Dojo提供了这个功能的模块,叫domReady,但是由于它很特殊,就在结尾加了个叹号 ...

  8. dojo Datagrid 实现数据删除功能

    DataGrid实现数据动态刷新功能见前一个帖子:http://www.cnblogs.com/qq552048250/p/4447103.html 实现数据删除只需要向表格中动态添加按钮,并为按钮的 ...

  9. Dojo初探之3:dojo的DOM操作、query操作和domConstruct元素位置操作(基于dojo1.11.2版本)

    前言: 前面两章讲了dojo的基本规范和配置,当然这个配置不是必须的,当你有这需求的时候就可以用到dojo的config配置. dojo的所有js都是符合AMD规范进行异步加载的:http://blo ...

随机推荐

  1. java.sql.SQLException: Incorrect string value:

    安装好MySQL一定先改字符集 如果没有,改完字符集之后,要把之前数据库重新创建一下.

  2. 【Fine原创】常见的HTTP错误码的具体含义整理

    常见的HTTP错误码的具体含义     "100" : Continue   客户端应当继续发送请求. "101" : witching Protocols   ...

  3. Eclipse的FindBugs插件

      Eclipse的FindBugs插件     问题提出: 当我们编写完代码,做完单元测试等各种测试后就提交正式运行,只能由运行的系统来检测我们代码是否有问题了,代码中隐藏的错误在系统运行的过程中被 ...

  4. [WPF]GridView或DataGrid中自定义样式:依据某一列设定其对应行的样式(背景色,字体等)

    附效果照一张: 本方法使用StyleSelector来 获得依据自定义逻辑的style. ① class ConditionalStyleSelector : StyleSelector { publ ...

  5. Spring3.0之后->Spring MVC过滤器-HiddenHttpMethodFilter

    浏览器form表单只支持GET与POST请求,而DELETE.PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET.POST.PUT ...

  6. devexpress xaf 开发中遇到的问题.

    devexpress xaf 开发中遇到的问题很多久了就忘记了.每天都把开发内容记录下来,方便大家,方便自己

  7. Linux 网络配置

    1. 查看网卡型号: lspci | grep -i ethernet 上图中显示了网卡的具体型号,可以根据这个网卡型号在Intel官网下载Linux版本的驱动. 2. 以太网开机启动: 以太网的配置 ...

  8. Apriori 关联分析算法原理分析与代码实现

    前言 想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事. 那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢? 这就是关联分析所要完成的任务了. 本文 ...

  9. split,slice,splice,replace的用法

    split()方法用于把一个字符串分割成字符串数组 str.split("字符串/正则表达式从该参数制定额地方分割str",可选,可指定返回数组的最大长度,如果没设置参数,整个字符 ...

  10. linux vsftp配置

    1.rpm -q ftp 查看是否安装ftp服务器 2.yum install vsftp 安装ftp服务器 3.修改配置文件/etc/vsftpd 下面的 ftpusers和user_list,这两 ...