如何进行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>
相关推荐
夏天想1 分钟前
vue2+elementui使用compressorjs压缩上传的图片
前端·javascript·elementui
The_cute_cat3 分钟前
JavaScript的初步学习
开发语言·javascript·学习
海天胜景6 分钟前
vue3 el-table 列增加 自定义排序逻辑
javascript·vue.js·elementui
烛阴20 分钟前
XPath 进阶:掌握高级选择器与路径表达式
前端·javascript
独立开阀者_FwtCoder31 分钟前
URL地址末尾加不加 "/" 有什么区别
前端·javascript·github
独立开阀者_FwtCoder34 分钟前
Vue3 新特性:原来watch 也能“暂停”和“恢复”了!
前端·javascript·github
前端小巷子1 小时前
跨域问题解决方案:开发代理
前端·javascript·面试
JohnYan1 小时前
Bun技术评估 - 07 S3
javascript·后端·bun
Mintopia1 小时前
Three.js 材质与灯光:一场像素级的光影华尔兹
前端·javascript·three.js
天涯学馆1 小时前
JavaScript 跨域、事件循环、性能优化面试题解析教程
前端·javascript·面试