什么是DOM?
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作。
DOM1级将HTML和XML文档形象地看作一个层次化的节点树,可以使用JavaScript来操作节点树,进而改变底层文档的外观和结构。
节点层次
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。
最基本的节点类型是Node,用于抽象地表示文档中一个独立的部分,所有其他类型都继承自Node。
节点类型:
Document:整个文档树的顶层节点Element:网页的各种HTML标签Text:标签之间或标签包含的文本Comment:注释DocumentType:doctype标签Attr:网页元素的属性
Node类型
每个节点都有一个nodeType属性,用于表示节点的类型。
不同节点的nodeType属性值和对应的常量如下。
- 元素节点(element):1,对应常量
Node.ELEMENT_NODE - 属性节点(attr):2,对应常量
Node.ATTRIBUTE_NODE - 文本节点(text):3,对应常量
Node.TEXT_NODE - 注释节点(Comment):8,对应常量
Node.COMMENT_NODE - 文档节点(document):9,对应常量
Node.DOCUMENT_NODE - 文档类型节点(DocumentType):10,对应常量
Node.DOCUMENT_TYPE_NODE
通过比较常量,可以确定节点的类型
var node = document.documentElement.firstChild;if(node.nodeType === Node.ELEMENT_NODE{console.log('该节点是元素节点');}
nodeName和nodeValue属性
nodeName属性返回节点的名称nodeValue属性返回一个字符串,表示当前节点本身的文本值。(文本节点、注释节点、属性节点可以返回结果,其他节点返回null)
<div id="outer">Hello,fanison</div>var div = document.getElementById('outer')div.nodeName // 'DIV'div.nodeValue // nulldiv.firstChild.nodeValue // 'Hello,fanison'
div是元素节点,nodeValue返回null;div.firstChild是文本节点,所有可以返回文本值
节点关系
文档中所有的节点之间都存在对应的关系,比如可以将body元素看成是html元素的子元素,html元素看成是body元素的父元素,head元素可以看成是body元素的兄弟元素。
每个节点都有一个childNodes属性,保存一个 NodeList类数组对象,可通过位置来访问节点(使用方括号或item()方法)
nextSibling返回紧跟在当前节点后面的第一个同级节点previousSibling返回当前节点前面的、距离最近的一个同级节点firstChild返回当前节点的第一个子节点lastChild返回当前节点的最后一个子节点
<div id="outer"><div id="d1">第1个div</div><div id="d2">第2个div</div><div id="d3">第3个div</div><div id="d4">第4个div</div></div>var outer = document.getElementById('outer');var d1 = document.getElementById('d1');var d2 = document.getElementById('d2');var d4 = document.getElementById('d4');d1.nextSibling === d2 // trued2.previousSibling === d1 // trueouter.firstChild === d1 // trueouter.lastChild === d4 // true
上面代码中,d1.nextSibling就是紧跟在d1后面的同级节点d2d2.previousSibling就是紧跟在d2前面的同级节点d1div元素的第一个子节点是d1,最后一个子节点是d4
注意:任意多个的空白符都将导致文本节点的插入,包括一个到多个空格符,换行符,制表符等等. 将显示 ‘#text’,因为在
操作节点
appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点 ```javascript第1个div第2个div第3个div第4个div
var outer = document.getElementById(‘outer’); var p = document.createElement(‘p’); outer.appendChild(p) var d2 = document.getElementById(‘d2’) outer.appendChild(d2)
<br />上面代码新建一个`<p>`节点,将其插入`outer`的尾部。<br />插入的是一个已经存在的节点`d2`,结果就是该节点会从原来的位置,移动到`outer`的尾部。- `insertBefore()`方法接受两个参数(`newNode,referenceNode`),将`newNode`将插在`referenceNode`节点的前面```javascriptvar outer = document.getElementById('outer');var p = document.createElement('p');var d1 = document.getElementById('d1')outer.insertBefore(p,d1)

上面代码新建一个<p>节点,插在d1的前面,也就是成为outer的第一个子节点。
removeChild()方法接受一个子节点作为参数,用于从当前节点移除该子节点var outer = document.getElementById('outer');var d1 = document.getElementById('d1');outer.removeChild(d1);

上面代码移除了d1节点,这个方法是在d1的父节点outer上调用的,不是在d1上调用的。
replaceChild()方法接受两个参数(newChild,oldChild),将一个新的newChild节点,替换当前oldChild节点var d1 = document.getElementById('d1')var newd1 = document.createElement('div');newd1.textContent = 'New div1';d1.parentNode.replaceChild(newd1,d1);

上面代码将d1节点替换成新的newd1节点
cloneNode()方法用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点 ```javascript var outer = document.getElementById(‘outer’); var outer2 = outer.cloneNode(false); document.body.appendChild(outer2);
var outer3 = outer.cloneNode(true); document.body.appendChild(outer3);
<a name="r1IWC"></a>### `outer2` 节点为浅拷贝,`outer3`节点为深拷贝(克隆子节点)<a name="sP6nA"></a>### Document类型<a name="4uYUt"></a>#### 特性- `nodeType` : 9- `nodeName`: #document- `nodeValue`: null- `parentNode`: null<a name="Dig4l"></a>#### 文档的子节点`documentElement`属性返回当前文档的根元素节点(root)```javascriptvar html = document.documentElement;html === document.childNodes[0];html === document.firstChild;
documentElement、firstChild、childNodes[0] 都指向元素
文档信息
document.title属性返回当前文档的标题document.URL属性返回一个字符串,表示当前文档的网址document.domain属性返回当前文档的域名,不包含协议和端口document.referrer属性返回一个字符串,表示当前文档的访问者来自哪里 ```javascript var originalTitle = document.title; document.title = ‘新标题’;
var url = document.URL; var domain = document.domain; var referrer = document.referrer;
<a name="0pvG9"></a>#### 查找元素`document.getElementById()`方法返回匹配指定`id`属性的元素节点<br />`document.getElementsByTagName()`方法搜索 HTML 标签名,返回符合条件的元素(返回一个类似数组的的对象)<br />`document.getElementsByName()`方法用于选择拥有`name`属性的 HTML 元素(返回一个类似数组的的对象)```javascript<div id="myDiv">Hello,fanison!</div>var div = document.getElementById('myDiv');var images = document.getElementByTagName('img'); // 返回当前文档的所有img元素节点console.log(images.length);var forms = document.getElementsByName('x');
文档写入
document.open方法清除当前文档所有内容,使得文档处于可写状态,供document.write方法写入内容document.close方法用来关闭document.open()打开的文档document.write方法用于向当前文档写入内容document.writeln方法用于向当前文档写入内容,并在输出内容的尾部添加换行符
Element类型
特性
nodeType: 1nodeName: 元素的标签名nodeValue: nullparentNode: Document或Element创建元素
document.createElement()创建新元素var div = document.createElement('div'); // 创建一个 div 元素
取得特性
getAttribute()返回元素指定的属性值var div = document.getElementById('myDiv');div.getAttribute('id') // myDiv
设置特性
setAttribute()接受两个参数:要设置的特性名和值removeAttribute()删除元素的特性
div.setAttribute('id','newDiv'); // 将id设置为 newDivdiv.removeAttribute('class')
Text类型
特性
nodeType: 3nodeName: #textnodeValue: 节点所包含的文本parentNode: Element创建文本节点
createTextNode()接受一个参数,要插入的节点中的文本
以上代码创建了一个新var element = document.createElement('div');element.className = 'message'var textNode = document.createTextNode("Hello,fanison!");element.appendChild(textNode);document.body.appendChild(element);
<div>元素并为它指定了值'message'的class属性,然后创建文本节点,将文本节点添加到元素中,再将元素添加到body中。分隔文本节点
splitText(): 将Text节点一分为二,变成两个相邻的Text节点。它的参数就是分割位置(从零开始),分割到该位置的字符前结束 ```javascriptHello,fanison!
var p = document.getElementById(‘p’); var textnode = p.firstChild;
var newText = textnode.splitText(6); newText // “Hello,” textnode // “fanison!”
以上代码将 textnode分隔成两个节点,newText节点为"Hello,",textnode节点为"fanison!"<br /><a name="FTUjF"></a>### Comment类型<a name="k4aYH"></a>#### 特性- `nodeType` : 8- `nodeName`: #comment- `nodeValue`: 注释的内容- `parentNode`: Document或Element<a name="ksQXv"></a>#### 创建`createComment()`创建注释节点```javascriptvar comment = document.createComment('A comment');
DocumentType类型
特性
nodeType: 10nodeName: doctype的名称nodeValue: nullparentNode: Document
DocumentFragment类型
特性
nodeType: 11nodeName: #document-fragmentnodeValue: nullparentNode: null创建
document.createDocumentFragment() 用于构建一个DOM结构,然后插入当前文档 ```javascript var fragment = document.createDocumentFragment(); // 等同于 var fragment = new DocumentFragment();
var li = document.createElement(‘li’); li.textContent = ‘Hello fanison’; fragment.appendChild(li); document.querySelector(‘ul’).appendChild(fragment);
上面代码创建了一个`DocumentFragment`节点,然后将一个`li`节点添加在它里面,最后将`DocumentFragment`节点移动到原文档。<a name="1Fbtd"></a>###<a name="C1xWK"></a>### Attr类型<a name="Bplt1"></a>#### 特性- `nodeType` : 2- `nodeName`: 特性的名称- `nodeValue`: 特性的值- `parentNode`: null<a name="X5QHs"></a>#### 方法- createAttribute() 创建并返回一个新的属性节点```javascriptvar attr = document.createAttribute('align');attr.value = 'left';element.setAttributeNode(attr)element.attributes(['align'].value) // 'left'element.getAttributeNode(['align'].value) // 'left'element.getAttribute('align') // 'left'
以上代码使用 createAttribute 创建新节点;使用 setAttributeNode将新创建的特性添加到元素中;使用 attributes属性、getAttributeNode()方法、getAttribute()方法可以访问。
CDATASelection类型
已废弃


