DOM之节点操作
节点操作
为啥学节点操作
获取元素通常使用两种方式
利用DOM提供的方法获取元素
document.getElementById();
document.getElementsByTagName();
document.querySelector();
等
利用节点层级关系获取元素
利用父子兄弟节点获取元素
逻辑性强 兼容性弱
节点概述
网页中的所有内容都是节点(标签、注释、文本、属性等)节点使用node表示
一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名字)、nodeValue(节点值)三个值基本属性。
元素节点 nodeType为1
属性节点 nodeType为2
文本节点 nodeType为3
节点层级
父节点
node.parentNode
返回的是最近的一父节点,没有返回null
子节点
parentNode.childNodes
返回的是一个集合,包含文本节点 不推荐
parentNode.children
返回子元素节点
parentNode.firstchild
返回第一子节点 文本节点 元素节点
parentNode.lastchild
返回最后一个子节点 文本节点 元素节点
parentNode.firstElementchild
返回第一个元素子节点 兼容性
parentNode.lastElementchild
返回最后一个元素子节点 兼容
实际开发
parentNode.children[]
兄弟节点 不常用
node.nextSibing
返回下一个兄弟节点
node.previousSibing
返回上一个兄弟节点
node.nextElementSibing
返回下一个兄弟元素节点
node.previousElementSibing
返回上一个兄弟元素节点
创建节点
document.creatElement(‘tagName’)
添加节点
node.appendChild
后面追加元素
node.insertBefore(chilld,指定元素)
前面追加元素
删除节点
node.removeChild() 方法
从 DOM 中删除一个子节点,返回删除的节点。
复制节点(克隆节点)
node.cloneNode() 方法
返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
注意:
- 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
- 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。
综合案例
案例:动态生成表格
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 案例分析
//因为里面的学生数据都是动态的,我们需要js 动态生成。 这里我们模拟数据,自己定义好数据。 数据我们采取对象形式存储。
//所有的数据都是放到tbody里面的行里面。
//因为行很多,我们需要循环创建多个行(对应多少人)
//每个行里面又有很多单元格(对应里面的数据),我们还继续使用循环创建多个单元格,并且把数据存入里面(双重for循环)
//最后一列单元格是删除,需要单独创建单元格。
//最后添加删除操作,单击删除,可以删除当前行。
var datas = [{
name: '小米',
subject: 'JavaScript',
score: 100
}, {
name: '小宝',
subject: 'JavaScript',
score: 98
}, {
name: '小小',
subject: 'JavaScript',
score: 99
}, {
name: '大大',
subject: 'JavaScript',
score: 88
}, {
name: '大猪蹄子',
subject: 'JavaScript',
score: 0
}];
// 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
var tbody = document.querySelector('tbody');
for(var i = 0; i < datas.length; i++ ){
var tr = document.createElement('tr');
tbody.appendChild(tr);
for(var k in datas[i]){
var td = document.createElement('td');
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除 </a>';
tr.appendChild(td);
}
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child)
tbody.removeChild(this.parentNode.parentNode)
}
}
</script>
</body>
</html>
效果如下
三种动态创建元素区别
document.write()
element.innerHTML
document.createElement()
区别
-
document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
-
innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
-
innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
-
createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 creatElement 高