获取元素通常使用的两种方式:
1.利用DOM提供的方法获取元素
document.getElementByid()
document.getElementsByTagName()
document.querySelector() 等
逻辑性不强,繁琐。
2.利用节点层级关系获取元素
利用父子兄弟节点关系获取元素
逻辑性强,但是兼容性稍差
节点概述
网页中的所有内容都是节点(标签,属性,文本,注释等),在DOM中节点使用node来表示。
HTML DOM树中的所有节点均可通过js进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。
一般的,节点至少拥有node Type(节点类型),node Name(节点名称)和node Value(节点值)这三个基本属性。
元素节点 nodeType 为1
属性节点 nodeType 为2
文本节点 nodeType 为3 (文本节点包括文字,空格,换行等)
在开发中,节点操作主要操作的是元素节点。
节点层级
利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。
1.父级节点
node.parentNode
<div class = "box">
<span class = "erw"></span>
</div>
var erw = document.querySelector('.erw');
erw.panentNode;
得到的是离元素最近的父级节点,如果找不到父节点就返回null
子节点
1. parentNode.childNodes (标准)
返回包含指定节点的子节点的集合,这个集合是即时更新的集合
子节点chileNode所有的子节点包含元素节点,文本节点等
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等
如果只想要获得里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
var ul = document.querySelector('ul'); for(var i = 0; i < ul.childNodes.length; i++){ if(ul.childNodes[i].nodeType == 1){ // ul.childNodes[i]是元素节点 console.log(ul.childNodes[i]); } }
2. parentNode.children (非标准)
这是一个只读属性,返回所以的子元素节点。它只返回子元素节点,其余子节点不返回。
虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。
子节点
1. parentNode.firstChild
firstChild返回第一个子节点,找不到则返回null,同样也是包含所有的节点。
2. parentNode.lastChild
lastChild返回最后一个子节点,找不到则返回null,同样也是包含所有的节点。
3. parentNode.firstElementChild
firstElementChild 返回的是第一个子元素节点,找不到返回null
4. parentNode.lastElementChild
lastElementChild 返回的是最后一个子元素节点,找不到则返回null
记住1,2是所有的节点,如换行,空格,文字。如果第一个或最后一个子节点是空格或换行,返回的就是空格或换行。3,4直接返回的是第一个或最后一个子元素节点,是元素,不包含其他的节点。
1. <ul><li>ab</li> <li>ab</li> <li>ab</li></ul> var ul = document.querySelector('ul'); var num = ul.firstChild; console.log(num); num.onclick = function(){ num.style.backgroundColor = 'pink'; } 2. <ul> <li>ab</li> <li>ab</li> <li>ab</li> </ul> // HTML的不同,结果会不一样。 var ul = document.querySelector('ul'); var num = ul.firstChild; console.log(num); num.onclick = function(){ num.style.backgroundColor = 'pink'; }
1. <ul><li>ab</li> <li>ab</li> <li>ab</li></ul> var ul = document.querySelector('ul'); var num = ul.firstElementChild; console.log(num); num.onclick = function(){ num.style.backgroundColor = 'pink'; } 2. <ul> <li>ab</li> <li>ab</li> <li>ab</li> </ul> var ul = document.querySelector('ul'); var num = ul.firstElementChild; console.log(num); num.onclick = function(){ num.style.backgroundColor = 'pink'; }
注意 :这两个方法有兼容性问题,IE9以上才支持 3,4有兼容。
在开发当中,firstChild和lastChild包含其他节点,操作不方便,而firstElementChild和lastElementChild有兼容性,那么如何获取第一个或最后一个子元素节点呢?
解决方案:
如果想要第一个子元素节点,可以使用parentNode.children[0]
如果想要最后一个子元素节点,可以使用parentNode.children[长度-1]
console.log(ul.children[ul.children.length-1]);
兄弟节点
1. node.nextSibling
nextSibling 返回当前元素的下一个兄弟节点,找不到则返回null,同样也是包含所以的节点。
2. node.previousSibling
previousSibling 返回当前元素上一个兄弟节点,找不到则返回null,同样包含所有的节点。
3. node.nextElementSibling
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null
4. node.previousElementSibling
previousElementSibling 返回当前元素上一个兄弟元素节点,找不到则返回null
3,4两个有兼容性问题,IE9以上才支持
如何解决兼容性问题:
// 自己封装一个兼容性的函数 function getNextElementSibling(element){ var el = element; while(el = el.nextSibling){ if(el.nodeType === 1){ return el; } } return null; }
创建节点
document.createElement('tagName')
document.createElement()方法创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
添加节点
node.appendChild(child)
node.appendChild()方法将一个节点添加到指定父节点的子节点列表表尾,类似于css中的after伪元素。
<ul> <li>1</li> <li>2</li> <li>3</li> </ul> // 1. 创建节点 元素节点 var li = document.createElement('li'); // 2. 添加节点 node.appendChild(child) node父级 child子级 var ul = document.querySelector('ul'); ul.appendChild(li); li.innerHTML = 'asd';
2. node.insertBefore(child,指定元素)
node.insertBefore()方法 将一个节点添加到父节点的指定子节点前面,类似css中的before伪元素。
<ul> <li>1</li> <li>2</li> <li>3</li> </ul> // 1. 创建节点 var li = document.createElement('li'); // 2. 添加节点 var ul = document.querySelector('ul'); ul.insertBefore(li,ul.children[1]); li.innerHTML = 'fgh';
ul.insertBefore(li,ul.children[1]);是将创建好的元素添加到ul的子节点中的第二个元素前面,[1]是索引号,如果想添加到第一个的前面就将1改为0,因为第一个元素的索引号是0
注意:只有先创建了节点后,才能进行添加节点。
删除节点
node.removeChild(child)
node.removeChild()方法从DOM中删除一个子节点,返回删除的节点。
<button>删除</button> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> // 1.获取元素 var ul = document.querySelector('ul'); var but = document.querySelector('button'); // 点击按钮依次删除里面的孩子 but.onclick = function(){ if(ul.children.length == 0){ this.disabled = true; } else { ul.removeChild(ul.children[0]); } }
复制节点
node.cloneNode()
node.cloneNode()方法返回调用该方法的节点的一个副本,也可称为克隆节点/拷贝节点
<ul> <li style="background-color: blue;">1</li> <li style="background-color: blueviolet;">2</li> <li style="background-color: brown;">3</li> </ul> var ul = document.querySelector('ul'); // 复制节点 根据索引号进行复制 var li = ul.children[1].cloneNode(true); // 添加节点 ul.appendChild(li);
注意:如果括号参数为空或false,则是浅拷贝,即克隆复制节点本事,不克隆里面的子节点
1. node.cloneNode(); 括号里内容为空或false,浅拷贝,只复制标签不复制内容。
2. node.cloneNode(true); 括号为true 深拷贝,复制标签,复制里面的内容。