Web前端入門第 71 問:JavaScript DOM 節(jié)點操作(增刪改)常用方法
有一個深有體會的事:發(fā)現(xiàn)現(xiàn)在很多前端同學,經(jīng)常用 Vue 開發(fā)項目之后,在某些需求場景要操作 DOM 節(jié)點的時,就不知道咋辦了~~
以前接手過其他開發(fā)團隊的項目,項目被漏洞掃描工具發(fā)現(xiàn)了異常,原因是用了一個 vue-video-player 插件用于播放視頻,這插件又依賴了低版本的 video.js 插件,而掃描工具發(fā)現(xiàn)的異常就是低版本的 video.js 插件存在安全問題,而且最新版的 vue-video-player 插件依賴都還存在問題,所以通過升級 vue-video-player 并不能解決問題,這時候就必須使用原生的 video.js 插件,而不能套用 vue-video-player 插件。
當時在改這個漏洞的時候就在想一個問題:為什么不直接使用 video.js 插件?而要使用一個上層封裝的 vue-video-player ?最后對比了兩個插件代碼才發(fā)現(xiàn),上層封裝的這個插件只是提供了相對簡單的 Vue 組件語法糖,而底層的 video.js 必須要針對 DOM 節(jié)點進行操作~~到這里大概就懂了當時開發(fā)這個功能的心思了,不太想寫原生代碼去操作 HTML 的 DOM 節(jié)點,畢竟 Vue 代碼寫習慣了,誰還會去寫 DOM 操作的方法呢?
開發(fā)建議
咱們在項目開發(fā)的時候,應該盡可能少的安裝三方依賴,如果三方依賴過多,不僅僅是代碼的體積增大,還會導致供應鏈拉長,在這些過多的供應鏈中,如果某個依賴包存在漏洞,那么這個漏洞就會傳播到項目,從而導致項目被攻擊,這就是攻防體系中的 供應鏈攻擊。
說回正題~~
DOM 操作
雖然 Vue/React 這些項目中咱們開發(fā)的時候不會寫 DOM 操作的邏輯方法,但它們的本質(zhì)還是離不開 DOM 節(jié)點的 增刪改,畢竟要更新瀏覽器頁面中的 HTML 元素,只能針對 DOM 節(jié)點進行操作。
創(chuàng)建 DOM 節(jié)點
常用的 DOM 節(jié)點操作方法就幾個,其他不太常用的就不在此處列舉~~
document.createElement(tagName)
document.createTextNode(text)
document.createComment(data)
示例:
// 創(chuàng)建元素節(jié)點
const div = document.createElement('div')
// 創(chuàng)建文本節(jié)點
const text = document.createTextNode('文本:前端路引')
// 創(chuàng)建注釋節(jié)點
const comment = document.createComment('注釋內(nèi)容:公眾號')
// 創(chuàng)建文檔片段
const fragment = document.createDocumentFragment()
// 向文檔片段中添加內(nèi)容
fragment.appendChild(div)
fragment.appendChild(text)
fragment.appendChild(comment)
// 將文檔片段添加到頁面中
document.body.appendChild(fragment)
文檔片段 這個方法是起到一個優(yōu)化批量操作的作用,如果每次創(chuàng)建一個節(jié)點就往頁面中添加,會導致頁面頻繁的回流重繪。使用 文檔片段 這種方法,將要插入的節(jié)點內(nèi)容,先緩存到文檔片段中,然后再一次性添加到頁面中,這樣,頁面就只會進行一次回流重繪,從而提高性能。

題外話:createComment 創(chuàng)建的注釋節(jié)點,不僅僅可用于文檔注釋說明,還能用于保存其他一些數(shù)據(jù)在注釋中,在需要的時候可以通過注釋獲取,比如:
const comment = document.createComment('注釋內(nèi)容')
comment.data = '公眾號:前端路引'
document.body.appendChild(comment)
// 在需要的時候,可以通過 data 屬性獲取數(shù)據(jù)內(nèi)容
console.log(comment.data)
所有的 HTML 節(jié)點上都可以新增自定義屬性,用于保存一些自定義數(shù)據(jù)內(nèi)容。
插入 DOM 節(jié)點
幾個 create 創(chuàng)建方法,是通過 document 對象調(diào)用,但是要往頁面中插入元素的時候,需要在要插入的節(jié)點上調(diào)用對應方法。
// 末尾插入
node.appendChild(node)
// 指定位置插入
node.insertBefore(newNode, referenceNode)
/*
更靈活的插入,position 支持
beforebegin 元素自身的前面。
afterend 元素自身的后面。
afterbegin 插入元素內(nèi)部的第一個子節(jié)點之前。
beforeend 插入元素內(nèi)部的最后一個子節(jié)點之后。
*/
element.insertAdjacentHTML(position, html)
示例:
<div id="container">
</div>
<script>
const container = document.querySelector('#container')
// 創(chuàng)建元素節(jié)點
const div = document.createElement('div')
div.textContent = '新文本節(jié)點:前端路引'
// 向 container 中添加 div
container.appendChild(div)
// 創(chuàng)建 span 節(jié)點
const span = document.createElement('span')
span.textContent = '這里是span節(jié)點'
// 在 div 前添加 span
container.insertBefore(span, div)
container.insertAdjacentHTML('beforebegin', `container 前面`)
container.insertAdjacentHTML('afterend', `container 后面`)
container.insertAdjacentHTML('afterbegin', `<div> container 內(nèi)部開頭</div>`)
container.insertAdjacentHTML('beforeend', `<div>container 內(nèi)部結(jié)尾</div>`)
</script>
運行結(jié)果:

DOM 節(jié)點刪除與替換
這類操作常用于刪除頁面中的某個元素,或者要將已經(jīng)存在的元素替換為新的 HTML 元素。
node.remove()
node.replaceChild(newNode, oldNode)
示例:
<div id="container">
<h2>這里是容器:</h2>
<div class="content">這里是內(nèi)容區(qū)域</div>
</div>
<script>
const container = document.querySelector('#container')
// 創(chuàng)建元素節(jié)點
const div = document.createElement('div')
div.textContent = '新文本節(jié)點:前端路引'
container.appendChild(div)
// 替換 .content 節(jié)點為 span 節(jié)點
const span = document.createElement('span')
span.textContent = '這里是span節(jié)點'
container.replaceChild(span, container.querySelector('.content'))
</script>
運行結(jié)果:

克隆節(jié)點
此方法用于復制節(jié)點,一般用于創(chuàng)建副本。
// deep=true 會克隆子節(jié)點
node.cloneNode(deep)
示例:
<div class="container">
<h2>這里是容器:</h2>
<div class="content">這里是內(nèi)容區(qū)域</div>
</div>
<script>
const container = document.querySelector('.container')
// 復制元素節(jié)點,不包含子節(jié)點
const clone = container.cloneNode()
document.body.appendChild(clone)
// 復制元素節(jié)點,包含子節(jié)點
const clone2 = container.cloneNode(true)
document.body.appendChild(clone2)
</script>
運行結(jié)果:

寫在最后
DOM 操作是最底層的方法,在 Vue/React 出現(xiàn)之前,jQuery 能統(tǒng)治一個時代,就是它內(nèi)部封裝了優(yōu)秀的 DOM 操作方法,通過一些 API 暴露封裝后更簡單的方法,讓前端不至于頻繁的去寫一些復雜的 DOM 操作代碼。
更多內(nèi)容參考 MDN:
https://developer.mozilla.org/zh-CN/docs/Web/API/Element
https://developer.mozilla.org/zh-CN/docs/Web/API/Node
文章首發(fā)于微信公眾號【前端路引】,歡迎 微信掃一掃 查看更多文章。
本文來自博客園,作者:前端路引,轉(zhuǎn)載請注明原文鏈接:http://www.rzrgm.cn/linx/p/18949429

浙公網(wǎng)安備 33010602011771號