JavaScript节点操作
文章目录
节点概述
网页中所有的内容都是节点(标签,属性,文本,注释),在Dom中,节点使用node来表示
HTML DOM树种的所有节点都可以通过js进行访问,所有的节点都可以被修改,也可以创建或者删除
节点拥有 nodeType(节点类型),nodeName(节点名称),nodeValue(节点值) 这三个基本属性
- 元素节点 nodeType 值为1
- 属性节点 nodeType 值为2
- 文本节点 nodeType 值为3(文本节点包含文字,空格,换行等)
注意:实际开发中,节点操作主要操作的是元素节点
节点层级
利用DOM树可以把节点划分为不同的层级关系,创建是父子兄层级关系
父级节点
node.parentNode
//parentNode 属性可以返回某节点的父节点,是最近的一个父节点
//如果指定的节点没有父节点返回null
子节点
所有子节点
parentNode.childNodes (标准) 返回包含指定节点的子节点的集合,该集合为即时更新的集合
注意:返回值里面包含思路所有的子节点,有元素节点,文本节点等
如果只想获取到里面的元素节点,需要专门处理
子元素节点
parentNode.children (非标准)
parentNode.children是一个只读属性,返回所有的子元素节点,它只返回子元素节点,其余节点不返回
虽然children 是一个非标准。得到了各个浏览器的支持
第1个子节点
parentNode.firstChild 返回第一个子节点,找不到返回null,也是包含了所有的节点
最后1个子节点
parentNode.lastChild返回最后一个子节点,找不到返回null,也是包含了所有的节点
第1个子元素节点
parentNode.firstElementChild 返回第一个子元素节点,找不到返回null
最后1个子元素节点
parentNode.lastElementChild返回最后一个子元素节点,找不到返回null
注意:firstElementChild 和lastElementChild 这两个方法有兼容性问题,IE9以上才支持
实际开发中firstChild和lastChild 包含其他节点,操作不方便,firstElementChild 和lastElementChild又有兼容性问题,如何操作呢
解决方案:
如果想要第一个子元素节点 可以使用 parentNode.children[0]
如果想要最后一个子元素节点 parentNode.children[parentNode.children.length-1]
兄弟节点
下一个兄弟节点
node.nextSibling 包含元素节点或者文本节点
上一个兄弟节点
node.previousSibling包含元素节点或者文本节点
下一个兄弟元素节点
node.nextElementSibling 只有元素节点
上一个兄弟元素节点
node.previousElementSibling只有元素节点
兼容问题
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伪元素
node.insertBefore()
node.insertBefore 将一个节点添加到父节点的指定子节点前面,类似于css里面的before伪元素
删除节点
node.removeChild() 从node节点中删除一个子节点,返回删除的节点
留言板案例
<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>Document</title>
</head>
<body>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul></ul>
<script>
/*
点击按钮,动态创建一个li。添加到ul里面
创建li的同时,把文本域里面的值通过innerHTML赋值给li
如果想要新的留言在后面显示 使用appendChild 在前面显示使用insertBefore
*/
// 1获取元素
var btn = document.querySelector('button')
var text = document.querySelector('textarea')
var ul = document.querySelector('ul')
// 注册事件
btn.onclick = function () {
// 1 先判断文本域中是否有值
if (text.value.length === 0) {
alert('你没有输入内容')
return
}
// 1 创建元素
var li = document.createElement('li')
// 给li赋值 添加删除按钮
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>"
console.log(li)
// 添加元素
// ul.appendChild(li)
ul.insertBefore(li, ul.children[0])
// 文本域内容清空
text.value = ''
// 删除元素 删除的是当前连接的li a的父节点 动态生成
var aArr = document.querySelectorAll('a')
// 循环给a注册事件
for (var i = 0; i < aArr.length; i++) {
aArr[i].onclick = function () {
// 删除的是li 当前a所在的li this.parentNode
ul.removeChild(this.parentNode)
}
}
}
</script>
</body>
</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>Document</title>
<style>
table {
width: 500px;
margin: 100px auto;
border: 1px solid;
border-collapse: collapse;
}
tr {
height: 40px;
}
td,
th {
border: 1px solid;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!--
1:里面的学生数据都是动态的,通过js动态生成,模拟数据,自己定义好数据,每一条数据以对象的形式进行存储
2:所有的数据 都放到tbody的行里面
3:行很多,循环创建多个行 一行是一个对象(一条数据)
4:每一行有很多个单元格,每一个单元格就是对象里的每一个数据,我们需要循环创建多个单元格
5:最后一列单元格是删除,需要单独创建单元格
5:最后添加删除操作,点击删除,删除当前行
-->
</body>
<script>
// 1模拟学生的数据
var data = [
{
name: '张三',
subject: 'javascript',
score: 100,
},
{
name: '李四',
subject: 'java',
score: 98,
},
{
name: '王五',
subject: 'python',
score: 34,
},
]
// 2 往tbody里面创建行,有几条数据(数组的长度) 我们就创建几行
var tbody = document.querySelector('tbody')
for (var i = 0; i < data.length; i++) {
// 创建tr行
var tr = document.createElement('tr')
tbody.appendChild(tr)
// 行里面创建单元格td,单元格的数量取决于每个对象里属性的个数
// 通过for..in循环遍历学生对象
for (var k in data[i]) {
// 创建单元格
var td = document.createElement('td')
td.innerHTML = data[i][k]
tr.appendChild(td)
}
// 创建存放删除的单元格
var td = document.createElement('td')
td.innerHTML = "<a href='javascript:;'>删除</a>"
tr.appendChild(td)
}
// 删除操作
var aArr = document.querySelectorAll('a')
for (var j = 0; j < aArr.length; j++) {
aArr[j].onclick = function () {
// 点击a 删除a所在的行 node.removeChile(child)
tbody.removeChild(this.parentNode.parentNode)
}
}
</script>
</html>
复制节点
node.cloneNode() 返回调用该方法的节点的一个副本,称为克隆节点
**注意:**node.cloneNode() 括号里是空或者false 浅拷贝 只复制标签不复制里面的内容
括号里为true 深拷贝 既赋值标签又复制里面的内容
创建元素的三种方式
document.write() 直接将内容写入页面的内容流,但是文档流执行完毕,它会导致页面全部重绘
element.innerHTML是将内容写入某个dom节点,不会导致页面全部重绘
document.createElement() 创建多个元素效率会低,但是结构更清晰
注意:innerHTML效率要不createElement的高
Dom的总结
文档对象模型(Document Object Model 简称Dom)是处理可扩展标记语言的标准编程接口
W3C定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式.
关于dom操作,主要针对的是元素的操作, 主要有创建,增,删,改,查,属性操作,事件操作
创建
1:document.write
2:innerHTML
3:createElement
增加
1:appendChild
2:innerBefore
删
removeChild
改
主要修改dom的元素属性,dom元素的内容,属性,表单的值
修改元素的属性 src href title
修改普通元素内容 innerHTML innerText
修改表单元素 value type disabled
修改元素样式 style className
查
获取查询dom的元素
1:getElementById getElementsByTagName
2:querySelector querySelectorAll
3:parentNode children previousElementSibling nextElementSibling
属性操作
自定义属性
setAttribute 设置dom的属性值
getAttribute 获取dom的属性值
removeAttribute 移除属性