所有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是 DOM 操作的基础
属性
1.Node.prototype.nodeType
nodeType属性返回一个整数值,表示节点的类型
document.nodeType // 9
文档节点(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
2.Node.prototype.nodeName
nodeName属性返回节点的名称
// HTML 代码如下
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeName // "DIV"
3.Node.prototype.nodeValue
nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值
// HTML 代码如下
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeValue // null
div.firstChild.nodeValue // "hello world"
4.Node.prototype.textContent
textContent属性返回当前节点和它的所有后代节点的文本内容
// HTML 代码为
// <div id="divA">This is <span>some</span> text</div>
document.getElementById('divA').textContent
// This is some text
5.Node.prototype.nextSibling
Node.nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null
// HTML 代码如下
// <div id="d1">hello</div><div id="d2">world</div>
var d1 = document.getElementById('d1');
var d2 = document.getElementById('d2');
d1.nextSibling === d2 // true
6.Node.prototype.previousSibling
previousSibling属性返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null
// HTML 代码如下
// <div id="d1">hello</div><div id="d2">world</div>
var d1 = document.getElementById('d1');
var d2 = document.getElementById('d2');
d2.previousSibling === d1 // true
7.Node.prototype.parentNode
parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)
if (node.parentNode) {
node.parentNode.removeChild(node);
}
上面代码中,通过node.parentNode属性将node节点从文档里面移除
8.Node.prototype.parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null
if (node.parentElement) {
node.parentElement.style.color = 'red';
}
9.Node.prototype.firstChild,Node.prototype.lastChild
firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null’
// HTML 代码如下
// <p id="p1"><span>First span</span></p>
var p1 = document.getElementById('p1');
p1.firstChild.nodeName // "SPAN"
10.Node.prototype.childNodes
childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点
var children = document.querySelector('ul').childNodes;
上面代码中,children就是ul元素的所有子节点。
使用该属性,可以遍历某个节点的所有子节点。
var div = document.getElementById('div1');
var children = div.childNodes;
for (var i = 0; i < children.length; i++) {
// ...
}
文档节点(document)就有两个子节点:文档类型节点(docType)和 HTML 根元素节点
var children = document.childNodes;
for (var i = 0; i < children.length; i++) {
console.log(children[i].nodeType);
}
// 10
// 1
方法
1.Node.prototype.appendChild()
appendChild方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点
var p = document.createElement('p');
document.body.appendChild(p);
2.Node.prototype.hasChildNodes()
hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点
var foo = document.getElementById('foo');
if (foo.hasChildNodes()) {
foo.removeChild(foo.childNodes[0]);
}
上面代码表示,如果foo节点有子节点,就移除第一个子节点。
注意,子节点包括所有类型的节点,并不仅仅是元素节点。哪怕节点只包含一个空格,hasChildNodes方法也会返回true
hasChildNodes方法结合firstChild属性和nextSibling属性,可以遍历当前节点的所有后代节点
function DOMComb(parent, callback) {
if (parent.hasChildNodes()) {
for (var node = parent.firstChild; node; node = node.nextSibling) {
DOMComb(node, callback);
}
}
callback(parent);
}
// 用法
DOMComb(document.body, console.log)
3.Node.prototype.insertBefore()
insertBefore方法用于将某个节点插入父节点内部的指定位置
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
insertBefore方法接受两个参数,第一个参数是所要插入的节点newNode,第二个参数是父节点parentNode内部的一个子节点referenceNode。newNode将插在referenceNode这个子节点的前面。返回值是插入的新节点newNode
4.Node.prototype.removeChild()
removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。
var divA = document.getElementById('A');
divA.parentNode.removeChild(divA);
上面代码移除了divA节点。注意,这个方法是在divA的父节点上调用的,不是在divA上调用的。
下面是如何移除当前节点的所有子节点。
var element = document.getElementById('top');
while (element.firstChild) {
element.removeChild(element.firstChild);
}
5.Node.prototype.replaceChild()
replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点
var replacedNode = parentNode.replaceChild(newChild, oldChild);
上面代码中,replaceChild方法接受两个参数,第一个参数newChild是用来替换的新节点,第二个参数oldChild是将要替换走的子节点。返回值是替换走的那个节点oldChild
var divA = document.getElementById('divA');
var newSpan = document.createElement('span');
newSpan.textContent = 'Hello World!';
divA.parentNode.replaceChild(newSpan, divA);
6.Node.prototype.normalize()
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 /
上面代码使用normalize方法之前,wrapper节点有两个毗邻的文本子节点。使用normalize方法之后,两个文本子节点被合并成一个。