JavaScript—节点
节点
网页中所有内容都是节点(标签、属性、文本、注释),在DOM中,节点使用node表示
HTML中,所有的节点都可以通过js访问,所有的节点都可以被修改,也可以被创建删除
节点拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)三个基本属性
- 元素节点 nodeType 值为1
- 属性节点 nodeType 值为2
- 文本节点 nodeType 值为3
- 文字
- 空格
- 换行
注意:实际开发中,节点操作主要操作的是元素节点
节点层级
通过DOM树可以把节点划分为不同的层级关系,创建父子兄层级关系
父级节点
node.parentNode
parentNode属性可以返回某节点的父节点,是最近的一个父节点
如果指定的节点没有父级节点,返回null
<body>
<div>这是div标记</div>
<span>这是span标记</span>
<ul>
<li>这是li标记</li>
<li>这是li标记</li>
<li>这是li标记</li>
<li>这是li标记</li>
</ul>
<div class="box">
<span class="erweima">这是个二维码</span>
</div>
<script>
// 1. 父级节点 parentNode
var oErWeiMa = document.querySelector('.erweima');
var oDiv = document.querySelector('.box');
console.log(oErWeiMa.parentNode);
console.log(document.documentElement.parentNode);
console.log(oDiv.parentNode);
</script>
</body>
子节点
childNodes
parentNode.childNodes(标准)
返回包含指定节点的子节点的集合,改集合为即使跟新的集合**注意:返回值里面包含了指定节点的所有子节点,包含元素节点、文本节点等
第一个子节点
parentNode.firstChild
返回第一个子节点,找不到返回null,也是包含了所有的节点
最后一个节点
parentNode.lastChild
返回最后一个子节点,找不到返回null,也是包含了所有的节点
子元素节点
parentNode.children(非标准)
parentNode.children是一个只读属性,返回所有的子元素节点,其余的节点不返回
第一个子元素节点
parentNode.firstElementChild
返回第一个子元素节点,找不到返回null
最后一个子元素节点
parentNode.lastElementChild
返回最后一个子元素节点,找不到返回null
注意:
实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而firstElementChild 和 lastElementChild 两个方法存在兼容性问题,IE9以上浏览器才支持。
解决方案:
如果想要第一个子元素节点,可以使用 parentNode.children[0];
如果想要最后一个子元素节点,可以使用 parentNode.children[parentNode.children.length-1];
<body>
<div>这是div标记</div>
<span>这是span标记</span>
<ul>
<li>这是第一个li标记</li>
<li>这是li标记</li>
<li>这是li标记</li>
<li>这是最后一个li标记</li>
</ul>
<div class="box">
<span class="erweima">这是个二维码</span>
</div>
<script>
// 2. 子节点 childNodes
var oUl = document.querySelector('ul');
var lis = oUl.querySelectorAll('li');
// 返回所有子节点集合
console.log(oUl.childNodes);
console.log(oUl.childNodes[0].nodeType);
console.log(oUl.childNodes[1].nodeType);
// 返回子元素节点集合
console.log(oUl.children);
console.log(oUl.children[0].nodeType);
console.log(oUl.children[1].nodeType);
// 获取第一个子元素节点
console.log(oUl.children[0]);
// 获取最后一个子元素节点
console.log(oUl.children[oUl.children.length-1]);
</script>
</body>
兄弟节点
上一个兄弟节点
perviousSibling
包含元素节点,本文节点等节点
下一个兄弟节点
nextSibling
包含元素节点,本文节点等节点
上一个兄弟元素节点
previousElementSibling
只包含元素节点
下一个兄弟元素节点
previousElementSibling
只包含元素节点
注意:同样的再查找上一个或下一个兄弟元素节点时,存在兼容性的问题
解决方案:构造一个查找兄弟节点的函数,当查找上一个或者下一个兄弟节点时,判断nodeType的值
<div>这是div标记</div>
<span id="aspan">这是span标记</span>
<ul>
<li>这是第一个li标记</li>
<li>这是li标记</li>
<li>这是li标记</li>
<li>这是最后一个li标记</li>
</ul>
<div class="box">
<span class="erweima">这是个二维码</span>
</div>
<script>
var oErWeiMa = document.querySelector('.erweima');
var oDiv = document.querySelector('.box');
var oSpan = document.querySelector('#aspan');
// 3. 兄弟节点
console.log(oSpan.nextSibling);
console.log(oSpan.previousSibling);
console.log(oSpan.nextElementSibling);
console.log(oSpan.previousElementSibling);
</script>
创建节点
document.createElement(“tagName”)
document.createElement(“tagName”) 方法创建由tagName指定的HTML元素,这些元素原先不存在
是根据我们的需求动态生成的,称为动态创建元素节点
添加节点
node.appendChild(child)
node.appendChild 将一个节点添加到指定节点的子节点列表末尾node.insertBefore(child)
node.insertBefore() 将一个节点添加到父节点的指定子节点前面
<ul>
<li>123</li>
</ul>
<script>
// 创建节点
var li = document.createElement('li');
var oUl = document.querySelector('ul');
// 添加节点
oUl.appendChild(li);
// oUl.insertBefore(li,oUl.children[0]);
console.log(oUl);
</script>
删除节点
node.removeChild(child);
当找不到删除的节点时,会报错;
<ul>
<li>123</li>
</ul>
<script>
// 创建节点
var li = document.createElement('li');
var oUl = document.querySelector('ul');
// 添加节点
oUl.appendChild(li);
// oUl.insertBefore(li,oUl.children[0]);
console.log(oUl);
oUl.removeChild(li);
克隆节点
node.cloneNode() 返回调用该方法节点的一个副本,称为克隆节点
var li1 = oUl.children[0].cloneNode();
var ul1 = oUl.cloneNode(false);
console.log(li1);
console.log(ul1);
var ul2 = oUl.cloneNode(true);
console.log(ul2);
综合案例
将数据动态的存入表格中,并添加删除操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态生成表格</title>
<style>
* {
margin: 0;
padding: 0;
}
table {
width: 400px;
border-collapse: collapse;
margin: 220px auto;
border: 1px solid black;
}
tr {
height: 40px;
}
td,
th {
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>年级</th>
<th>专业</th>
<th>班级</th>
<th>删除</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script>
// 创建一个学生对象集合
var student = [
{
name: '王梦德',
grade: 2019,
subject: '计算机科学与技术',
class: '三班'
},
{
name: '范玉霞',
grade: 2018,
subject: '数字媒体技术',
class: '二班'
},
{
name: '王五',
grade: 2020,
subject: '物联网',
class: '一班'
}
]
// 为表格添加数据
var tbody = document.querySelector('tbody');
for (var i = 0; i < student.length; i++) {
// 为表格添加行
var tr = document.createElement('tr');
// tbody.appendChild(tr);
for (var key in student[i]) {
// 为每行添加单元格
var td = document.createElement('td');
// 为单元格添加数据
td.innerHTML = student[i][key];
tr.appendChild(td);
}
// 为最后一列操作列添加操作
// 这里创建的单元格名为td不影响,因为上面的操作已经做完
// 但是加以区分命名为td1
var td = document.createElement('td');
td.innerHTML = "<a href = 'javascript:;'>删除</a>"
// 将每个行添加到表格中
tr.appendChild(td);
// 将建好的每行添加到表格中
tbody.appendChild(tr);
}
var aArr = document.querySelectorAll('a');
for (i = 0; i < aArr.length; i++) {
aArr[i].onclick = function () {
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
</body>
</html>