DOM 就是文档的数据结构,它提供了操作文档的编程接口 API。
10.1 节点层次
文档是由节点组成的树形结构,根节点是文档节点 Documet
,其下是 html
元素节点。
10.1.1 Node 类型
节点的类型
总共有 12 种类型的节点,使用 Node
类可以判断一个节点的类型。注意:在 IE 中只能使用数值,不能使用常量。
常量 | 值 | 说明 |
---|---|---|
Node.ELEMENT_NODE |
1 | 元素节点 |
Node.ATTRIBUTE_NODE |
2 | 属性节点 |
Node.TEXT_NODE |
3 | 文本节点 |
Node.CDATA_SECTION_NODE |
4 | 数据节点 |
Node.ENTITY_REFERENCE_NODE |
5 | |
Node.ENTITY_NODE |
6 | |
Node.PROCESSING_INSTRUCTION_NODE |
7 | |
Node.COMMENT_NODE |
8 | 注释节点 |
Node.DOCUMENT_NODE |
9 | 文档节点 |
Node.DOCUMENT_TYPE_NODE |
10 | 文档类型节点 |
Node.DOCUMENT_FRAGMENT_NODE |
11 | |
Node.NOTATION_NODE |
12 |
if (someNode.nodeType == 1){ //使用数值可以在所有浏览器下工作
alert("Node is an element.");
}
节点的信息
每个节点都有 nodeType
、nodeName
和 nodeValue
三个属性,可以了解节点的信息。
if (someNode.nodeType == 1){
value = someNode.nodeName; //将会返回标签名
}
不同节点各属性的含义
不同类型的节点,nodeName
和 nodeValue
的意义不一样,因此,一般情况下要先判断节点类型。
元素节点各属性的含义
名称 | 说明 |
---|---|
nodeName |
元素的标签名称,等同之前的 tagName |
nodeType |
1 |
nodeValue |
元素节点没有值,所以返回 null |
属性节点各属性的含义
名称 | 说明 |
---|---|
nodeName |
属性名称 |
nodeType |
2 |
nodeValue |
属性值 |
文本节点各属性的含义
名称 | 说明 |
---|---|
nodeName |
#text |
nodeType |
3 |
nodeValue |
文本内容(不包含 html) |
节点的关系
节点的层次结构可以划分为:父子节点、 兄弟节点这两种。 利用节点的层次结构可以获取节点树上的任意其他节点
属性 | 说明 |
---|---|
childNodes |
获取当前元素节点的所有子节点,返回一个 NodeList 对象 |
parentNode |
获取当前节点的父节点 |
previousSibling |
获取当前节点的前一个同级节点,第一个节点会返回 null |
nextSibling |
获取当前节点的后一个同级节点,最后一个节点会返回 null |
firstChild |
获取当前元素节点的第一个子节点 |
lastChild |
获取当前元素节点的最后一个子节点 |
ownerDocument |
获取该节点的文档根节点,相当于文档对象 document |
hasChildNodes |
判断是否有子节点 |
子节点列表
获取字节的的属性 childNodes
是个列表对象,可以像数组一样访问它
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
也可以用数组的 slice
方法将 childNodes
对象转换为数组
//在 IE8 之前不工作
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
节点的增删改查
方法 | 说明 |
---|---|
appendChild |
将新节点追加到子节点列表的末尾,返回添加的节点 |
insertBefore |
将新节点插入在某个节点的前面,返回被插入的节点 |
repalceChild |
将新节点替换旧节点,返回被替换的节点 |
removeChild |
移除节点,返回被移除的节点 |
cloneNode |
克隆一个节点,可以深克隆,也可以浅克隆 |
添加节点
var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
如果被添加的节点是已经文档中的节点,那么节点将被移动位置
//将第一个节点移动到最后
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild); //false
alert(returnedNode == someNode.lastChild); //true
插入节点
//位置参数为 Null,则插入到最后
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
//插入到第一个
returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true
//插入到倒数第二个
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true
深克隆和浅克隆
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3 (IE < 9) or 7 (others)
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0
10.1.2 Document 类型
文档对象代表整个页面文档,是 DOM 的根节点,它是只读的,因此不能添加、删除、替换子节点。其下一般只有惟一一个 html
子节点,是系统自动创建的
属性 | 值 |
---|---|
nodeType |
9 |
nodeName |
"#document" |
nodeValue |
null |
parentNode |
null |
ownerDocument |
null |
子节点 |
可以有一个 DocumentType 一个 Element 或者一个注释等等 |
文档对象的属性
除了具有普通节点的属性和方法之外,document 对象还有一些快捷属性
属性 | 说明 |
---|---|
document.documentElement | 返回文档包含的子节点,指向 html 元素 |
document.body | 指向 body 元素 |
document.doctype | 指向 doctype 元素,各个浏览器对这个属性不一致,因此不常用 |
document.title | 返回文档标题 |
document.URL | 返回文档的链接 |
document.referrer | 返回链接到当前页面的那个页面的链接,可能为空 |
document.domain | 返回域名,不能设置为 URL 中不包含的域 |
document.documentElement 的例程
var html = document.documentElement; //返回 元素对象
alert(html === document.childNodes[0]); //true
alert(html === document.firstChild); //true
文档对象的域
修改域的时候,只能修改子域
//page from p2p.wrox.com
document.domain = "wrox.com"; //成功
document.domain = "nczonline.net"; //不在同一个域中,出错!
设置为同样的主域名,不同页面之间的对象可以进行通信
//page from p2p.wrox.com
document.domain = "wrox.com"; //可以通信
document.domain = "p2p.wrox.com"; //这样不能通信
查找元素
利用文档对象可以查找元素对象。
注意,必须等文档加载完毕,才能查找和操作 DOM 操作对象,可以将相关代码放在 onload 事件中
方法 | 说明 |
---|---|
document.getElementsById | 返回一个元素 |
document.getElementsByTagName | 返回同一种标签的集合,可以用通配符 |
document.getElementsByName | 返回有相同名字的元素集合,可以用通配符 |
元素集合
getElementsByTagName 和 getElementsByName 这两个查找方法会返回元素的集合
var images = document.getElementsByTagName("img");
alert(images.length); //output the number of images
alert(images[0].src); //output the src attribute of the first image
alert(images.item(0).src); //output the src attribute of the first image
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];
特殊集合的快捷访问
文档对象有几个属性,可以直接获取某些元素集合
属性 | 说明 |
---|---|
document.anchors | 锚点集合 |
document.applets | 小程序集合 |
document.forms | 表单集合 |
document.images | 图像集合 |
document.links | 链接集合 |
DOM 一致性检测
DOM 本身分很多级别,不同浏览器实现的程度也有所不同,可以用 document.implementation.hasFeature 方法检测
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
下面的表格时可以进行检测的功能和版本号
功能 | 版本号 | 说明 |
---|---|---|
Core | 1.0, 2.0, 3.0 | |
XML | 1.0, 2.0, 3.0 | |
HTML | 1.0, 2.0 | |
Views | 2.0 | |
StyleSheets | 2.0 | |
CSS | 2.0 | |
CSS2 | 2.0 | |
Events | 2.0, 3.0 | |
UIEvents | 2.0, 3.0 | |
MouseEvents | 2.0, 3.0 | |
MutationEvents | 2.0, 3.0 | |
HTMLEvents | 2.0 | |
Range | 2.0 | |
Traversal | 2.0 | |
LS | 3.0 | |
LS-Async | 3.0 | |
Validation | 3.0 |
文档写入
document.write
方法可以向文档写入内容,有两个需要注意的地方
- 包含
""
这个特殊字符串的时候要转义一下 - 当文档加载完毕后调用
document.write
方法,将重写整个文档
document.write("