dom学习笔记(DOM/Node类型/关系节点/操作节点)
DOM
DOM(Document Object Model): 是针对HTML和XML文档的一个API(Application Program Interface)。
DOM描绘了一个层次化的节点树,允许开发人员添加,移除,修改页面的一部分。
换言之,DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
文档节点是每个文档的根节点,文档节点只有一个子节点(例如<html>
)。
<html>
元素又成为文档元素,每个文档只能有一个文档元素。
DOM节点
HTML 文档中的所有内容都是节点。共有12种节点类型。
- 整个文档是一个文档节点
- 每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 注释是注释节点
Node类型
DOM1级定义了Node接口,在js中作为Node类型实现(除IE不能访问这个类型)。
js中所有节点都继承这个类型,所有节点类型都共享着相同的基本属性和方法。
12种节点类型,用12个数值常亮表示。
- 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)
// 获取ELEMENT_NODE节点类型值(IE中无效,IE 没有公开 Node 类型的构造函数)
Node.ELEMENT_NODE
// 通过节点的nodeType属性获取节点类型
document.nodeType
9
// nodeType保存的是元素的标签名
document.nodeName
"#document"
// nodeValue
document.nodeValue
null
节点关系
关系指针都是只读的。
childNodes
每个节点都有一个childNodes
属性,保存着NodeList对象。
NodeList并不是Array的实例,他保存着一组有序
的节点,也有length属性(值为保存的节点的个数)。
NodeList是基于DOM结构动态执行查询的结果,DOM结果变化能够自动反应到NodeList对象中。
// 访问NodeList对象
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
// 将NodeList转换为数组
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
// 或
function convertToArray(nodes){
var array = null;
try {
array = Array.prototype.slice.call(nodes, 0); //针对非 IE 浏览器
} catch (ex) {
array = new Array();
for (var i=0, len=nodes.length; i < len; i++){
array.push(nodes[i]);
}
}
return array;
}
parentNode
指向文档树中的父节点
previousSibling/nextSibling
previousSibling:访问同一个列表中的前一个节点
nextSibling:访问同一个列表中的后一个节点
if (someNode.nextSibling === null){ // 最后一个节点
alert("Last node in the parent’s childNodes list.");
} else if (someNode.previousSibling === null){ // 第一个节点
alert("First node in the parent’s childNodes list.");
}
if (someNode.nextSibling === someNode.previousSibling) {
// 判断列表只有一个节点
}
hasChildNodes
该节点是否包含子节点
ownerDocument
所有节点都有ownerDocument属性,指向整个文档的文档节点,表示任何节点都属于它所在的文档。
任何节点不能同时存在于俩个或更多文档。可以直接访问文档节点。
document.ownerDocument
null
操作节点
将DOM树看成是由一系列指针链接起来。任何DOM节点不能同时出现在文档中的多个位置。
替换和移除的节点依然为文档所有,只是没有自己的位置了。
以下四种方法必须在取得父节点情况下使用。
在不支持子节点的节点使用下面四种方法会报错。
appendChild()
- 当添加的节点为新节点
向 childNodes 列表的末尾添加一个节点。 - 添加的节点是文章的一部分
将该节点从原来的位置转移到最后一个节点位置。
var returnedNode = someNode.appendChild(newNode); 返回添加的节点
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
insertBefore()
把节点放在 childNodes 列表中某个特定的位置上. 这个方法接受两个参数:要插入的节点和作为参照的节点。插入节点后,被插 入的节点会变成参照节点的前一个同胞节点( previousSibling ),同时被方法返回。
//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
//插入后成为第一个子节点
var 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
replaceChild()
替换指定节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。 该节点的所有关系指针都会从被它替换的节点复制过来。
接受两个参数:要插入的节点和要替换的节点
//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild); // 返回被替换的节点
//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
removeChild()
移除节点。
//移除第一个子节点
var formerFirstChild = someNode.removeChild(someNode.firstChild); // 返回被移除的节点
//移除最后一个子节点
var formerLastChild = someNode.removeChild(someNode.lastChild);
其他方法
cloneNode()
对调用这个方法的节点创建一个完全相同的副本。复制后返回的节点副本属于文档所有, 但并没有为它指定父节点。通过 appendChild() 、 insertBefore() 或 replaceChild() 将它 添加到文档中。
接受布尔值参数:
true:执行深复制,也就是复制节点及其整个子节点树
false:执行浅复制,即只复制节点本身
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3(IE < 9)或 7(其他浏览器)
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0
cloneNode() 方法不会复制添加到 DOM 节点中的 JavaScript 属性,例如事件处 理程序等。这个方法只复制特性、(在明确指定的情况下也复制)子节点,其他一切 都不会复制。IE 在此存在一个 bug,即它会复制事件处理程序,所以我们建议在复制 之前最好先移除事件处理程序。
normalize()
处理文档树中的文本节点.
由于解析器的实现或 DOM 操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点
的情况。如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。