DOM操作

浏览器解析HTML文档被后会创建一颗DOM树,若要改变HTML结构,则需要通过js来操作DOM树。操作DOM其实也就是对DOM树的DOM节点进行查找、修改、删除、插入。
一、查找DOM节点
在对DOM
节点进行操作前,首先需要获取DOM
节点。获取DOM
节点的方式有:
-
getElementById()
:根据html
标签的id获取,由于id在html文档里面是唯一的,所以这种方式可以定位唯一一个DOM节点html<div class="container"> <div id="header"> id选择 </div> <div id="content"> <p>这是一个段落</p> </div> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> <script> // id选择 const header = document.getElementById('header') console.log(header.innerHTML) // id选择 // 获取子节点 const ch = header.children const first = header.firstElementChild const last = header.lastElementChild </script>
-
getElementByTagName() 与 getElementsByClassName()
,前者是根据HTML标签名来获取DOM节点 ,后者是根据标签类名来获取DOM节点 ,这两种种方式总是返回一组DOM节点。返回的对象是一个类数组对象
HTMLCollection
,不是数组所以不同使用数组的方法jsconst divs = document.getElementsByTagName('div') console.log(Object.prototype.toString.call(divs)) // [object HTMLCollection] // 类 const boxs = document.getElementsByClassName('box') console.log(Object.prototype.toString.call(boxs))// [object HTMLCollection]
-
querySelector()与querySelectorAll()
:CSS选择器获取DOM节点,前者是获取第一个匹配的DOM节点,后者是获取所有匹配的节点js// css 选择 const header2 = document.querySelector('#header2') console.log(header2.innerHTML) //css选择器 // 获取所有类名为box的div const box2 = document.querySelectorAll('div.box') console.log(box2.length) // 3
二、修改DOM节点
-
纯文本内容修改
对
textContext 或 innerText
属性进行操作,可以获取/修改存文本内容(不解析html),innerText
不返回隐藏元素的文本(如display: none
或visibility: hidden
),而textContent
返回所有文本。innerText
它会触发 回流(reflow) ,因为需要计算样式 (它会考虑 CSS 样式,只返回 用户实际可见的文本),textContent
它不关心 CSS 样式,直接获取 DOM 中的文本,性能更好,因为它不涉及样式计算。
html<div id="container"> Visible text <div style="display:none">Hidden text</div> </div>
jsconst ex = document.getElementById('container') console.log(ex.textContent) // Visible text Hidden text console.log(ex.innerText) // Visible text
-
修改
innerHTML
属性innerHTML
不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树html<div id="container"> <h1>这是一个标题</h1> <p>这是一个段落</p> </div> <script> const container = document.querySelector('#container') console.log(container.innerHTML) // <h1>这是一个标题</h1> <p>这是一个段落</p> container.innerHTML = '<strong>加粗文本</strong>' console.log(container.innerHTML) // <strong>加粗文本</strong> </script>
如果写入的字符串是通过网络拿到的,要注意对字符编码来避免XSS攻击。
-
修改CSS
通过
DOM
节点的style
属性可以修改标签的样式,DOM节点的style
属性对应所有的CSS,可以直接获取或设置要注意的是 :由于CSS允许
font-size
这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize
。html<div id="container"></div>
jsconst e = document.getElementById('container') e.style.backgroundColor = 'red' e.style.width = '100px' e.style.height = '100px' e.style.border = '1px solid black'
三、删除DOM节点
删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild
把自己删掉
html
<div class="container">
<header class="hrader"></header>
<main class="main"></main>
<footer class="footer"></footer>
</div>
js
const e = document.querySelector('.container')
console.log(e.innerHTML)
/*
<header class="hrader"></header>
<main class="main"></main>
<footer class="footer"></footer>
*/
e.removeChild(e.querySelector('.footer'))
console.log(e.innerHTML)
/*
<header class="hrader"></header>
<main class="main"></main>
*/
删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。
四、插入DOM节点
-
插入DOM节点可以使用直接使用
innerHTML
,但是这样会将DOM原有的内容直接覆盖,若这个DOM节点是空节点则可以这样做,若不是则不能使用这种方式。当然也可以使用 e.innerHTML += '',来增加内容而不是覆盖。html<div></div> <script> const e = document.querySelect('div') e.innerHTML = '<h1>这是一个标题</h1>' </script>
结果如下:
html<div> <h1>这是一个标题</h1> </div>
-
可以使用**
appendChild()
,把一个子节点添加到父节点的最后一个子节点**html<div id="other"></div> <div class="container"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> <script> const other = document.querySelector('#other') const container = document.getElementsByClassName('container')[0] // 插入已经存在的节点 container.appendChild(other) // 插入新创建的节点 const p = document.createElement('p') container = appendChild(p) </script>
HTML结构变成如下:因为我们插入的
js
节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。若节点是新创建的节点,则不会有上述问题。html<div class="container"> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div id="other"></div> <p id="text">这是一个段落</p> </div>
-
insertBefore(newNode,refNode)
可以将一个节点插入到另一个节点的前面,不过需要先获取节点所在的父级节点和插入节点的位置html<div class="container"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> <script> const container = document.getElementsByClassName("container")[0]; // 插入到第一个box之前 const firstBox = document.querySelectorAll(".box")[0]; const p = document.createElement("p"); p.innerHTML = "我是p标签"; container.insertBefore(p, firstBox); </script>
html<div class="container"> <p>我是p标签</p><div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div>