DOM,Node 接口
最后更新于:2022-04-02 03:25:59
[TOC]
## Node 接口
### 属性
#### Node.prototype.nodeType 节点类型,返回整数
`document.nodeType`
* 文档节点(document):9,对应常量`Node.DOCUMENT_NODE`
* 元素节点(element):1,对应常量`Node.ELEMENT_NODE`
* 属性节点(attr):2,对应常量`Node.ATTRIBUTE_NODE`
* 文本节点(text):3,对应常量`Node.TEXT_NODE`
* 文档片断节点(DocumentFragment):11,对应常量`Node.DOCUMENT_FRAGMENT_NODE`
* 文档类型节点(DocumentType):10,对应常量`Node.DOCUMENT_TYPE_NODE`
* 注释节点(Comment):8,对应常量`Node.COMMENT_NODE`
#### Node.prototype.nodeName 节点名称
```
var div = document.getElementById('d1');
div.nodeName // "DIV"
```
* 文档节点(document):`#document`
* 元素节点(element):大写的标签名
* 属性节点(attr):属性的名称
* 文本节点(text):`#text`
* 文档片断节点(DocumentFragment):`#document-fragment`
* 文档类型节点(DocumentType):文档的类型
* 注释节点(Comment):`#comment`
#### Node.prototype.nodeValue 节点值
文本节点(text)、注释节点(comment)和属性节点(attr)有文本值
```
// HTML 代码如下
//
`
#### Node.prototype.nextSibling 后面最近的同级节点
```
//
';
hello world
var div = document.getElementById('d1');
div.nodeValue // null
div.firstChild.nodeValue // "hello world"
```
#### Node.prototype.textContent 当前和后台节点内容
属性是可读写的,且复制标签会自动转义
```
// This is some text
document.getElementById('divA').textContent
// This is some text
```
`document.getElementById('foo').textContent = 'GoodBye!
'; ` #### Node.prototype.baseURI ``` // http://www.example.com/index.html document.baseURI // "http://www.example.com/index.html" ``` 设置了base 就会返回此属性 `hello
world
var d1 = document.getElementById('d1');
var d2 = document.getElementById('d2');
d1.nextSibling === d2 // true
```
遍历子节点
```
var el = document.getElementById('div1').firstChild;
while (el !== null) {
console.log(el.nodeName);
el = el.nextSibling;
}
```
#### Node.prototype.previousSibling 前面最近的同级节点
#### Node.prototype.parentNode 父节点
#### Node.prototype.parentElement 父元素节点,只返回元素节点
与`parentNode`的区别
由于父节点只可能是三种类型:元素节点、文档节点(`document`)和文档片段节点(`documentfragment`)。`parentElement`属性相当于把后两种父节点都排除了
#### Node.prototype.firstChild,Node.prototype.lastChild 返回当前节点的子节点
```
// First span
var p1 = document.getElementById('p1'); p1.firstChild.nodeName // "SPAN" ``` //如果有换行,则返回文本节点 ``` //// First span //
var p1 = document.getElementById('p1'); p1.firstChild.nodeName // "#text" ``` #### Node.prototype.childNodes 返回当前所有子节点 包括文本节点和属性节点 ``` var children = document.querySelector('ul').childNodes; ``` #### Node.prototype.isConnected 节点是否在文档中 ``` var test = document.createElement('p'); test.isConnected // false document.body.appendChild(test); test.isConnected // true ``` ### 方法 #### Node.prototype.appendChild() 作为最后子节点,插入 如果 Dom 节点已经存在,则是移动位置 ``` var p = document.createElement('p'); document.body.appendChild(p); ``` #### Node.prototype.hasChildNodes() 是否有子节点 ``` var foo = document.getElementById('foo'); if (foo.hasChildNodes()) { //存在就移除节点 foo.removeChild(foo.childNodes[0]); } ``` > 注意,子节点包括所有类型的节点,并不仅仅是元素节点。哪怕节点只包含一个空格,hasChildNodes方法也会返回true #### Node.prototype.cloneNode() 克隆节点, 参数为 `true` 递归克隆 `var cloneUL = document.querySelector('ul').cloneNode(true); ` `addEventListener`方法和`on-`属性(即`node.onclick = fn`),添加在这个节点上的事件回调函数 #### Node.prototype.insertBefore() 节点插入父节点内部的指定位置 `var insertedNode = parentNode.insertBefore(newNode, referenceNode); ` 第一个参数是所要插入的节点`newNode`, 第二个参数是父节点`parentNode`内部的一个子节点`referenceNode`。`newNode`将插在`referenceNode`这个子节点的前面。返回值是插入的新节点`newNode` 例子: ``` var p = document.createElement('p'); document.body.insertBefore(p, document.body.firstChild); ``` #### Node.prototype.removeChild() 移除节点,参数为获取的节点 ``` var divA = document.getElementById('A'); divA.parentNode.removeChild(divA); ``` 移除当前节点的所有子节点: ``` var element = document.getElementById('top'); while (element.firstChild) { element.removeChild(element.firstChild); } ``` #### Node.prototype.replaceChild() 替换某个子节点 `var replacedNode = parentNode.replaceChild(newChild, oldChild); ` NewSpan 替换 divA ``` var divA = document.getElementById('divA'); var newSpan = document.createElement('span'); newSpan.textContent = 'Hello World!'; divA.parentNode.replaceChild(newSpan, divA); ``` #### Node.prototype.contains() 参数节点为当前节点,或子节点,或后代节点 `document.body.contains(document.body.firstChild)` * 参数节点为当前节点。 * 参数节点为当前节点的子节点。 * 参数节点为当前节点的后代节点。 #### Node.prototype.compareDocumentPosition() 与`contains`方法类似,返回二进制 | 二进制值 | 十进制值 | 含义 | | --- | --- | --- | | 000000 | 0 | 两个节点相同 | | 000001 | 1 | 两个节点不在同一个文档(即有一个节点不在当前文档) | | 000010 | 2 | 参数节点在当前节点的前面 | | 000100 | 4 | 参数节点在当前节点的后面 | | 001000 | 8 | 参数节点包含当前节点 | | 010000 | 16 | 当前节点包含参数节点 | | 100000 | 32 | 浏览器内部使用 | ``` var head = document.head; var body = document.body; if (head.compareDocumentPosition(body) & 4) { console.log('文档结构正确'); } else { console.log(' 不能在 前面'); } ``` #### Node.prototype.isEqualNode() 两节点是否相等 ``` var p1 = document.createElement('p'); var p2 = document.createElement('p'); p1.isEqualNode(p2) // true ``` 所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同 #### Node.prototype.### isSameNode() 是否为同一个节点 ``` var p1 = document.createElement('p'); var p2 = document.createElement('p'); p1.isSameNode(p2) // false p1.isSameNode(p1) // true ``` #### Node.prototype.normalize() 清理当前节点内部的所有文本节点(text) ``` var wrapper = document.createElement('div'); wrapper.appendChild(document.createTextNode('Part 1 ')); wrapper.appendChild(document.createTextNode('Part 2 ')); wrapper.childNodes.length // 2 wrapper.normalize(); wrapper.childNodes.length // 1 ``` #### Node.prototype.getRootNode() 与`ownerDocument`属性的作用相同 ``` document.body.firstChild.getRootNode() === document // true document.body.firstChild.getRootNode() === document.body.firstChild.ownerDocument // true ``` ## NodeList 接口,HTMLCollection 接口 节点数组 `NodeList`可以包含各种类型的节点,`HTMLCollection`只能包含 HTML 元素节点 ## ParentNode 接口,ChildNode 接口 ### ParentNode 接口 **如果有子节点,它就继承 `Parent`接口** #### ParentNode.children ``` for (var i = 0; i < el.children.length; i++) { // ... } ``` 只包含元素子节点,动态变化 #### ParentNode.firstElementChild 首个元素节点 ``` document.firstElementChild.nodeName // "HTML" ``` #### ParentNode.lastElementChild #### ParentNode.childElementCount #### ParentNode.append(),ParentNode.prepend() 在最前/最后添加元素 ``` var p1 = document.createElement('p'); var p2 = document.createElement('p'); parent.append(p1, p2); ``` ### ChildNode 接口 如果一个节点有父节点,那么该节点就继承了`ChildNode`接口 #### ChildNode.remove() 移除当前节点 `el.remove() ` #### ChildNode.before(),ChildNode.after() 从之前,之后插入节点 可插入元素节点,也可插入文本节点 ``` var p = document.createElement('p'); var p1 = document.createElement('p'); // 插入元素节点 el.before(p); // 插入文本节点 el.before('Hello'); // 插入多个元素节点 el.before(p, p1); // 插入元素节点和文本节点 el.before(p, 'Hello'); ``` ### ChildNode.replaceWith() 参数节点替换当前节点 ``` var span = document.createElement('span'); el.replaceWith(span); ``` ### NodeList 接口 `document.body.childNodes instanceof NodeList // true ` 1.并不是数组,但有 `length` 与 `forEach` 2.可转成数组 `Array.prototype.slice.call(children)` ### HTMLCollection 接口 只能包含元素节点,不能使用`foreach` 一些对象的合集 `document.links`、`document.forms`、`document.images` `document.links instanceof HTMLCollection // true ` 如果元素节点有`id`或`name`属性,那么`HTMLCollection`实例上面,可以使用`id`属性或`name`属性引用该节点元素。如果没有对应的节点,则返回`null` ``` // var pic = document.getElementById('pic'); document.images.pic === pic // true ```