节点概述
网页中的所有内容都是节点(标签,属性,文本,注释等),在DOM中节点使用node来表示,HTML DOM树中的所有的节点均可通过javascript进行访问,所有HTML元素节点均可被修改,创建,删除。
一般地,节点至少用
nodeType
(节点类型),nodeName
(节点名称)和nodeValue
(节点值)这三个基本属性
常见的节点
Element
元素节点nodeType为1
Attr
属性节点nodeType为2
Text
文本节点nodeType为3(文本节点包含文字,空格,换行等)
comment
注释节点 节点类型是 8
documentFragment
文档片段节点 节点类型是 11
document
文档节点 根节点 节点类型是9
我们在实际开发中,节点操作主要的是元素节点
节点层级
利用DOM树可以把节点划分不同的层级关系,常见的是父子兄层级关系
节点的关系包含两种:上下父子关系 相邻兄弟关系
在节点树中,最顶端的节点被称作为根节点 document
除了根节点之外,每一个节点都有自己的父节点
每一个节点都可以包含任何数量的子节点
叶子(属性)没子节点
同级的节点拥有同一个父节点
父级节点
- node.parentNode
parentNode属性可返回某节点的父节点,注意的是最近的一个父节点
如果指定的节点没有父节点则返回null
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ul>
<div class="demo">
<div class="box">
<span class="erweima"></span>
</div>
</div>
//1.父节点parentNode
var erweima = document.querySelector('.erweima');
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('li');
//得到的是离元素最近的父级节点(亲爸爸),如果找不到父节点就返回为null
console.log(erweima.parentNode);
子节点
parentNode.childNodes(标准)
parentNode.children(非标准)
-
parentNode.firstChild
:回第一个子节点,找不到则返回null。同样,也是包含所有的节点。 -
parentNode.lastChild
:返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。 -
parentNode.firstElementChild
:返回第一个子元素节点,找不到则返回null -
parentNode.lastElementChild
:返回最后一个子元素节点,找不到则返回null
注意:这两个方法有兼容性问题,IE9以上才支持
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ul>
<div class="demo">
<div class="box">
<span class="erweima"></span>
</div>
</div>
//子节点childNodes得到所有的节点包含元素节点和文本节点
console.log(ul.childNodes);
//遍历ul中所有的子节点
for(var i=0;i<ul.childNodes.length;i++){
if(ul.childNodes[i].nodeType == 1){
console.log(ul.childNodes[i]);
}
}
//children 获取所有的子元素节点
console.log(ul.children); //[li,li,li,li]
//firstChild 第一个节点 不管是文本节点还是元素节点
console.log(ul.firstChild);
console.log(ul.lastChild);
//返回第一个子元素节点
console.log(ul.firstElementChild);
//返回最后一个子元素节点
console.log(ul.lastElementChild);
/*
* 实际开发中,firstChild和lastChild包含其他节点,操作不方便
* 而firstElementChild和lastElementChild又有兼容性问题,那么我们
* 如何获取第一个子元素节点或最后一个子元素节点呢?
*
* 解决方案
* 实际开发的写法既没有兼容性问题又返回第一个子元素
* */
console.log(ul.children[0]);
console.log(ul.children[ul.children.length - 1]);
兄弟节点
-
node.nextSibling
:返回当前元素的下一个兄弟节点,找不到则返回null。同样,也是包含所有的节点 -
node.previousSibling
:返回当前元素的上一个兄弟节点,找不到则返回null。同样,也是包含所有的节点 -
node.nextElementSibling
:返回当前元素下一个兄弟元素的节点,找不到则返回null. -
node.previousSiling
:返回当前元素上一个兄弟元素的节点,找不到则返回null.
注意: nextElementSibling
和previousSiling
这两个方法有兼容性问题,IE9以上才支持。
<div>我是div</div>
<span>我是span</span>
var div = document.querySelector('div');
console.log(div.nextSibling);
console.log(div.previousSibling);
console.log(div.nextElementSibling);
/*
* 自己封装一个兼容性的函数
* */
function getNextElementSibling(ele) {
var el = element;
while(el == el.nextSibling){
if(el.nodeType === 1){
return el;
}
}
return null;
}
删除节点
node.removeChild(child);
方法从DOM中删除一个子节点,返回删除的节点
<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>关头强</li>
</ul>
/*
*node.removeChild(child);方法从DOM中删除一个子节点,返回删除的节点
* */
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
console.log(ul.removeChild(ul.children[0]));
btn.onclick = function () {
if(ul.children.length == 0){
this.disabled = true;
}else {
ul.removeChild(ul.children[0]);
}
}
复制节点
node.cloneNode()方法返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
注意:
1.如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点,不克隆里面的子节点
2.如果括号参数为true,则是深拷贝,会复制节点本身以及里面所有的子节点
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
var ul = document.querySelector('ul');
ul.appendChild(ul.children[0].cloneNode());
ul.appendChild(ul.children[0].cloneNode(true));