老镜 發表於 2025-6-26 10:36:00

Web前端入门第 71 问:JavaScript DOM 节点操作(增删改)常用方法

<p>有一个深有体会的事:发现现在很多前端同学,经常用 Vue 开发项目之后,在某些需求场景要操作 DOM 节点的时,就不知道咋办了~~</p>
<p>以前接手过其他开发团队的项目,项目被漏洞扫描工具发现了异常,原因是用了一个 <code>vue-video-player</code> 插件用于播放视频,这插件又依赖了低版本的 <code>video.js</code> 插件,而扫描工具发现的异常就是低版本的 <code>video.js</code> 插件存在安全问题,而且最新版的 <code>vue-video-player</code> 插件依赖都还存在问题,所以通过升级 <code>vue-video-player</code> 并不能解决问题,这时候就必须使用原生的 <code>video.js</code> 插件,而不能套用 <code>vue-video-player</code> 插件。</p>
<p>当时在改这个漏洞的时候就在想一个问题:为什么不直接使用 <code>video.js</code> 插件?而要使用一个上层封装的 <code>vue-video-player</code> ?最后对比了两个插件代码才发现,上层封装的这个插件只是提供了相对简单的 Vue 组件语法糖,而底层的 <code>video.js</code> 必须要针对 DOM 节点进行操作~~到这里大概就懂了当时开发这个功能的心思了,不太想写原生代码去操作 HTML 的 DOM 节点,毕竟 Vue 代码写习惯了,谁还会去写 DOM 操作的方法呢?</p>
<h2 id="开发建议">开发建议</h2>
<p>咱们在项目开发的时候,应该尽可能少的安装三方依赖,如果三方依赖过多,不仅仅是代码的体积增大,还会导致供应链拉长,在这些过多的供应链中,如果某个依赖包存在漏洞,那么这个漏洞就会传播到项目,从而导致项目被攻击,这就是攻防体系中的 <code>供应链攻击</code>。</p>
<p>说回正题~~</p>
<h2 id="dom-操作">DOM 操作</h2>
<p>虽然 Vue/React 这些项目中咱们开发的时候不会写 DOM 操作的逻辑方法,但它们的本质还是离不开 DOM 节点的 <code>增删改</code>,毕竟要更新浏览器页面中的 HTML 元素,只能针对 DOM 节点进行操作。</p>
<h3 id="创建-dom-节点">创建 DOM 节点</h3>
<p>常用的 DOM 节点操作方法就几个,其他不太常用的就不在此处列举~~</p>
<pre><code class="language-js">document.createElement(tagName)
document.createTextNode(text)
document.createComment(data)
</code></pre>
<p>示例:</p>
<pre><code class="language-js">// 创建元素节点
const div = document.createElement('div')
// 创建文本节点
const text = document.createTextNode('文本:前端路引')
// 创建注释节点
const comment = document.createComment('注释内容:公众号')

// 创建文档片段
const fragment = document.createDocumentFragment()
// 向文档片段中添加内容
fragment.appendChild(div)
fragment.appendChild(text)
fragment.appendChild(comment)

// 将文档片段添加到页面中
document.body.appendChild(fragment)
</code></pre>
<p><code>文档片段</code> 这个方法是起到一个优化批量操作的作用,如果每次创建一个节点就往页面中添加,会导致页面频繁的<code>回流重绘</code>。使用 <code>文档片段</code> 这种方法,将要插入的节点内容,先缓存到文档片段中,然后再一次性添加到页面中,这样,页面就只会进行一次回流重绘,从而提高性能。</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202506/596097-20250626103455856-1293112607.png"></p>
<p>题外话:<code>createComment</code> 创建的注释节点,不仅仅可用于文档注释说明,还能用于保存其他一些数据在注释中,在需要的时候可以通过注释获取,比如:</p>
<pre><code class="language-js">const comment = document.createComment('注释内容')
comment.data = '公众号:前端路引'
document.body.appendChild(comment)

// 在需要的时候,可以通过 data 属性获取数据内容
console.log(comment.data)
</code></pre>
<p><strong>所有的 HTML 节点上都可以新增自定义属性,用于保存一些自定义数据内容。</strong></p>
<h3 id="插入-dom-节点">插入 DOM 节点</h3>
<p>几个 create 创建方法,是通过 document 对象调用,但是要往页面中插入元素的时候,需要在要插入的节点上调用对应方法。</p>
<pre><code class="language-js">// 末尾插入
node.appendChild(node)

// 指定位置插入
node.insertBefore(newNode, referenceNode)

/*
更灵活的插入,position 支持
beforebegin 元素自身的前面。
afterend 元素自身的后面。
afterbegin 插入元素内部的第一个子节点之前。
beforeend 插入元素内部的最后一个子节点之后。
*/
element.insertAdjacentHTML(position, html)
</code></pre>
<p>示例:</p>
<pre><code class="language-html">&lt;div id="container"&gt;
&lt;/div&gt;

&lt;script&gt;
const container = document.querySelector('#container')

// 创建元素节点
const div = document.createElement('div')
div.textContent = '新文本节点:前端路引'

// 向 container 中添加 div
container.appendChild(div)

// 创建 span 节点
const span = document.createElement('span')
span.textContent = '这里是span节点'

// 在 div 前添加 span
container.insertBefore(span, div)

container.insertAdjacentHTML('beforebegin', `container 前面`)
container.insertAdjacentHTML('afterend', `container 后面`)
container.insertAdjacentHTML('afterbegin', `&lt;div&gt; container 内部开头&lt;/div&gt;`)
container.insertAdjacentHTML('beforeend', `&lt;div&gt;container 内部结尾&lt;/div&gt;`)
&lt;/script&gt;
</code></pre>
<p>运行结果:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202506/596097-20250626103503836-888771094.png"></p>
<h3 id="dom-节点删除与替换">DOM 节点删除与替换</h3>
<p>这类操作常用于删除页面中的某个元素,或者要将已经存在的元素替换为新的 HTML 元素。</p>
<pre><code class="language-js">node.remove()
node.replaceChild(newNode, oldNode)
</code></pre>
<p>示例:</p>
<pre><code class="language-html">&lt;div id="container"&gt;
&lt;h2&gt;这里是容器:&lt;/h2&gt;
&lt;div class="content"&gt;这里是内容区域&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
const container = document.querySelector('#container')

// 创建元素节点
const div = document.createElement('div')
div.textContent = '新文本节点:前端路引'
container.appendChild(div)

// 替换 .content 节点为 span 节点
const span = document.createElement('span')
span.textContent = '这里是span节点'
container.replaceChild(span, container.querySelector('.content'))
&lt;/script&gt;
</code></pre>
<p>运行结果:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202506/596097-20250626103508853-389087143.png"></p>
<h3 id="克隆节点">克隆节点</h3>
<p>此方法用于复制节点,一般用于创建副本。</p>
<pre><code class="language-js">// deep=true 会克隆子节点
node.cloneNode(deep)
</code></pre>
<p>示例:</p>
<pre><code class="language-html">
&lt;div class="container"&gt;
&lt;h2&gt;这里是容器:&lt;/h2&gt;
&lt;div class="content"&gt;这里是内容区域&lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
const container = document.querySelector('.container')

// 复制元素节点,不包含子节点
const clone = container.cloneNode()
document.body.appendChild(clone)

// 复制元素节点,包含子节点
const clone2 = container.cloneNode(true)
document.body.appendChild(clone2)
&lt;/script&gt;
</code></pre>
<p>运行结果:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202506/596097-20250626103516138-1929362447.png"></p>
<h2 id="写在最后">写在最后</h2>
<p>DOM 操作是最底层的方法,在 Vue/React 出现之前,jQuery 能统治一个时代,就是它内部封装了优秀的 DOM 操作方法,通过一些 API 暴露封装后更简单的方法,让前端不至于频繁的去写一些复杂的 DOM 操作代码。</p>
<p>更多内容参考 MDN:</p>
<p>https://developer.mozilla.org/zh-CN/docs/Web/API/Element<br>
https://developer.mozilla.org/zh-CN/docs/Web/API/Node</p>


</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/18949429</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/18949429
頁: [1]
查看完整版本: Web前端入门第 71 问:JavaScript DOM 节点操作(增删改)常用方法