如何进行DOM操作?

DOM操作

浏览器解析HTML文档被后会创建一颗DOM树,若要改变HTML结构,则需要通过js来操作DOM树。操作DOM其实也就是对DOM树的DOM节点进行查找、修改、删除、插入。

一、查找DOM节点

在对DOM节点进行操作前,首先需要获取DOM节点。获取DOM节点的方式有:

  1. 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>
  2. getElementByTagName() 与 getElementsByClassName() ,前者是根据HTML标签名来获取DOM节点 ,后者是根据标签类名来获取DOM节点 ,这两种种方式总是返回一组DOM节点。

    返回的对象是一个类数组对象HTMLCollection,不是数组所以不同使用数组的方法

    js 复制代码
            const 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]
  3. 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节点

  1. 纯文本内容修改

    对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>
    js 复制代码
    const ex = document.getElementById('container')
    console.log(ex.textContent) // Visible text  Hidden text
    console.log(ex.innerText) // Visible text
  2. 修改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攻击。

  3. 修改CSS

    通过DOM节点的style属性可以修改标签的样式,DOM节点的style属性对应所有的CSS,可以直接获取或设置

    要注意的是 :由于CSS允许font-size这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize。

    html 复制代码
    <div id="container"></div>
    js 复制代码
    const 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节点

  1. 插入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>
  2. 可以使用**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>
  3. 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>
相关推荐
wengad1 小时前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
行者-全栈开发2 小时前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
怕浪猫4 小时前
2026年金九银十,我面了22个前端
前端·javascript·面试
前端的日常4 小时前
一个人+AI做情侣食谱小程序,30天纯赚
前端·javascript·后端
qq_316837754 小时前
阿里云百炼 fun-asr-realtime uniapp vue3 调用
javascript·vue.js·uni-app
默_笙5 小时前
🚊 别再让 AI 的记忆写两遍了:PostgreSQL 把关系查询和语义检索装进一张表
前端·javascript
lzhdim5 小时前
C#不为人知的10个魔法特性:资深开发者也会震惊的底层奥秘
java·前端·javascript·算法·c#
只睡四小时6 小时前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航
喵个咪8 小时前
GoWind Admin|风行 — 开箱即用的企业级全栈中后台框架:脚本系统实战
javascript·后端·go
樱花落木兰8 小时前
SpringBoot + ECharts 后台数据统计报表模块实战
java·javascript·spring boot·ai·log4j·github·echarts