如何进行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: nonevisibility: 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>
相关推荐
林太白3 分钟前
Nuxt3 功能篇
前端·javascript·后端
YuJie4 分钟前
webSocket Manager
前端·javascript
wycode28 分钟前
Promise(一)极简版demo
前端·javascript
浮幻云月30 分钟前
一个自开自用的Ai提效VsCode插件
前端·javascript
不在了情绪1 小时前
HTML 简明教程
html
代码改变世界100861 小时前
像素风球球大作战 HTML 游戏
前端·游戏·html
艾小码1 小时前
Vue 3全面解析:Composition API、响应式原理与生态
前端·javascript·vue.js
Process1 小时前
面试官:Vue和React源码里用到了哪些设计模式?
前端·javascript·面试
华仔啊1 小时前
Vue3+TS设计模式:5个真实场景让你代码更优雅
前端·javascript·vue.js
兮漫天1 小时前
bun + vite7 的结合,孕育的 Robot Admin 【靓仔出道】(十六)
前端·javascript·vue.js