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. React Native工作小技巧及填坑记录

    以下是本人在React Native开发工作中使用的一些小技巧,记录一下. 1.从网络上拉取下来的React Native缺少React和React Native库. 终端 1. cd 项目根目录 2 ...

  2. CentOS7.1配置源

    现在网上最新的是CentOS7.1, 但是在配置国内流行的163源的时候,网上的文章大多数我这里都通不过. 错误信息大概是: One of the configured repositories fa ...

  3. 什么是 JSON ?

    什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 JSON ...

  4. oracle行转列,decode 等用法

    DECODE()函数,它将输入数值与函数中的参数列表相比较,根据输入值返回一个对应值.函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式.当然,如果未能与任何一个实参序偶匹配成功,则函数也有默 ...

  5. Intent中的四个重要属性——Action、Data、Category、Extras

    Intent作为联系各Activity之间的纽带,其作用并不仅仅只限于简单的数据传递.通过其自带的属性,其实可以方便的完成很多较为复杂的操作.例如直接调用拨号功能.直接自动调用合适的程序打开不同类型的 ...

  6. C# 加载 SQLite DLL问题

    /********************************************************************************* * C# 加载 SQLite DL ...

  7. Tomcat笔记

    总体架构: 由三部分组成:Service.Connector.Container 多个Connector对应一个Container,构成一个Service 为Service提供一个生存环境 如何处理多 ...

  8. js之路

    开始记录js学习: udacity,edx上不去: 搞了一个html+css+JavaScript后开始看es6; 犀牛书,js启示录,你不知道的js上中: 第一个库jQuery及源码分析: --

  9. 关于超出部分隐藏加省略号的css方法

    单行效果:display:block;     white-space:nowrap;  overflow:hidden;    text-overflow:ellipsis; 多行效果:width: ...

  10. 迅达云s3cmd客户端mac平台部署说明

    自己根据文档整理了下,在这里记下,免得其他兄弟走弯路. 1 下载最新的s3cmd代码 https://github.com/s3tools/s3cmd/archive/master.zip 2 解压缩 ...