节点操作
dom节点操作可以归纳为增删改查,查的操作直接获取该节点,然后在控制台打印,如果有同学不会的话可以看看上集。
操作 | 步骤 | 注意事项 |
创建节点(增) | 1.let xx=document.createElement('div') //新建节点 2.父节点.appendChild(子节点) //节点上树 |
新建的节点并没有挂载到DOM树上,必须要通过appendChild()方法追加到树上 |
移动节点(改) | 新父节点.appendChild(已有的父节点) | 无 |
删除节点(删) | 父节点.removeChild(要删除子结点); | 无 |
代码
<!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>Document</title>
<style>
</style>
</head>
<body>
<h2>优秀的程序员</h2>
<div id="div1">
<p id="p1">优秀的程序员必备三件套</p>
<ul id='ul1'>
<li>秃头</li>
<li>格子衫</li>
<li>拖鞋</li>
</ul>
</div>
</body>
<script>
// 获取节点
let div1 = document.getElementById('div1')
// 新增节点
const div2 = document.createElement('div')
// 节点上树
div1.appendChild(div2)
// 追加样式
div2.style.width = '200px'
div2.style.height = '100px'
div2.style.border = 'solid 1px red'
// ________________________________________
// 移动节点
const ul1 = document.getElementById('ul1')
div2.appendChild(ul1);
// ________________________________________
// 删除节点
const p1 = document.getElementById('p1')
div1.removeChild(p1)
</script>
</html>
打印结果:
结果1:在id=‘div1’的标签内部增加一个div标签,并追加样式
结果2:把ul标签移动到div2内部
结果3:删除div1内部的p标签
节点类型
我们先打印一下ul1这个父节点
// 获取节点
let ul1 = document.getElementById('ul1')
console.log(ul1.childNodes)
大家肯定会带着两个疑惑:
1.text是啥?
2.明明在li标签前面没有写任何的文本,为什么会有text这玩意?
疑惑解答
DOM规定文档中的每个成分都是一个节点(Node),DOM节点有:
类型 | 功能 |
元素节点(Element) | 其实就是标签,例如<p>、<div>、<ul> |
文本节点(Text) | 你能在浏览器页面中看见的东西,比如:上述页面中‘优秀的程序员’ |
属性节点(Attr) | 元素属性,比如<a>标签的链接属性href="*"。 |
属性节点在这里先不讲,所以text就是文本节点,就是我们在浏览器中所能看见的东西,但是为什么li标签外面也有文本节点呢?我放一张图给大家看就知道了!
没错,那堆空格也算是文本!所以把那堆空格删除了,ChildNodes就只剩下li标签。
在这里介绍给大家两个判断DOM节点的属性:nodeName和nodeType。
属性 | 功能 |
nodeType | nodeType = 1 //元素节点 nodeType = 3 //文本节点 nodeType = 8 //注释节点 nodeType = 9 //document节点 nodeType = 10 //DTD节点 |
nodeName | 元素节点返回元素名称 文本节点返回 #text |
大家可以根据DOM的节点属性,封装一个API去筛选出元素节点。
DOM性能
为什么要讲性能这块呢,因为dom操作就像香港的土地,寸土寸金,是非常“昂贵的”,dom操作有可能会导致浏览器重新渲染,而且占用的cpu也比较多,如果频繁操作会导致卡顿等问题。
比如我们想要在div标签里面插入十个p标签,通常我们都会这样做:
<body>
<div id="div1"></div>
</body>
<script>
const div1 = document.getElementById('div1');
for (let i = 0; i < 10; i++) {
const p1 = document.createElement('p');
p1.innerHTML = `this is p${i}`;
div1.appendChild(p1);
}
</script>
打印结果如下:
的确,我们可以把想要的结果打印出来,但是这个代码段的性能太差了,每一次让子结点上树和追加文本都会进行dom渲染一次,加大CPU的负担(好比我叫你拿十本书上五楼,你非得要一次拿一本上来,那会不会有亿点点累?)
那我们有什么方法优化呢?没错!既然我们分十次拿十本书,为什么我们不能一次性都拿上五楼?所以同样的解决方法,我们不在循环里面操作,把每次插入这个操作打包成一个整体,一块插进去就好了。
const div1 = document.getElementById('div1');
const bag = document.createDocumentFragment()
for (let i = 0; i < 10; i++) {
const p1 = document.createElement('p');
p1.innerHTML = `this is p${i}`;
bag.appendChild(p1);
}
div1.appendChild(bag);
执行步骤
1.获取div1标签,通过createDocumentFragment()创建一个文件片段(把十本书拿上五楼之前准备一个书包)
2.for循环里面在bag中插入新的‘p’结点(就是把那十本书一本一本地放进书包)
3.把bag文件片段插入到div1中(把书包拿上五楼之后给我)
创作不易,路过的朋友可以动一下您的发财小手点个赞吗?码完字干饭去!
今天你学废了吗?