DOM操作总结  (。♥ᴗ♥。) 哇!!

article/2025/10/19 14:24:46
知识点
  • DOM 本质
  • DOM 节点操作
  • DOM 结构操作
  • DOM 性能

前言

各种框架层出不穷,但DOM操作一直都会是前端工程师的基础,必备知识。
只会Vue和React等框架,而不懂DOM操作的前端程序员们。。。在这里插入图片描述

DOM的本质?

Do you know?

在这里插入图片描述
首先,先了解一下什么是xml 。 上代码:

<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

XML (可扩展标记语言 EXtensible Markup Language)
XML 是一种标记语言, 被设计用来传输和存储数据,而非显示数据(HTML就被设计用来显示数据)
XML使用的标签没有被预定义,你需要自行定义标签。
SGML、HTML、XML、XHTML、HTML5 之间的关系,知道否?

HTML是一种特殊的XML。它遵循W3C的规定,各种规定,必须先写什么,怎么写什么。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><div><p>跟着W3C标准,有饭吃。。。ヽ( ̄▽ ̄)</p></div>
</body>
</html>

在这里插入图片描述
那么如果是一个字符串对象(html一大坨)的话,让浏览器,js处理是非常不方便的。
如何查询,如何操作等等比较麻烦。所以浏览器拿到代码之后。。。
DOM可以理解为浏览器把拿到的html代码,结构化一个浏览器能识别并且js可操作的一个模型而已(也就是DOM结构树)

树结构什么的不要我讲了吧在这里插入图片描述

DOM 节点操作

获取 DOM 节点

  • 通过元素类型的方法来操作:
  1. document.getElementById(); //id名,在实际开发中较少使用,选择器中多用class id一般只用在顶级层存在 不能太过依赖id
  2. document.getElementsByTagName(); //标签名
  3. document.getElementsByClassName(); //类名
  4. document.getElementsByName(); //name属性值,一般不用
  5. document.querySelector(); //css选择符模式,返回与该模式匹配的第一个元素,结果为一个元素;如果没找到匹配的元素,则返回null
  6. document.querySelectorAll() //css选择符模式,返回与该模式匹配的所有元素,结果为一个类数组

注意:

  • 前缀为document,意思是在document节点下调用这些方法,当然也可以在其他的元素节点下调用哦!
  • querySelector()querySelectorAll()两个方法为静态的,不是实时的,保存的是当时的状态,是一个副本,即:在以后的代码中通过方法使所选元素发生了变化,但该值依然不会改变,因此使用有局限性,一般不用,除非就想得到副本。
    在这里插入图片描述
  • 根据关系树来获取节点(遍历节点树):
    根据前面,我们已经知道:DOM(文档对象模型)可以将任何HTML、XML文档描绘成一个多层次的节点树。所有的页面都表现为以一个特定节点为根节点的树形结构。html文档中根节点为document节点。
    在这里插入图片描述
    所有节点都有nodeType属性,代表节点的不同类型,通过nodeType属性可以来判断节点的类型。

经常使用的节点主要有以下几种类型:

  1. Element类型(元素节点):nodeType值为 1
  2. Text类型(文本节点):nodeType值为 3
  3. Comment类型(注释节点):nodeType值为 8
  4. Document类型(document节点):nodeType值为 9

其规定的一些常用的属性有:

  • document.body document.head 分别为HTML中的 <body> <head>
  • document.documentElement<html>标签

所有的节点都有 hasChildNodes()方法,用来判断有无子节点 有一个或多个子节点时返回true

通过一些属性可以来遍历节点树:

  1. parentNode //获取所选节点的父节点,最顶层的节点为#document
  2. childNodes //获取所选节点的子节点们
  3. firstChild //获取所选节点的第一个子节点
  4. lastChild //获取所选节点的最后一个子节点
  5. nextSibling //获取所选节点的后一个兄弟节点 列表中最后一个节点的nextSibling属性值为null
  6. previousSibling //获取所选节点的前一兄弟节点 列表中第一个节点的previousSibling属性值为null

注意:
由于文档中的节点类型较多,遍历子节点的结果很多时候并不能得到我们想要的结果。
小心哦!!空文本也是文本节点!
使用遍历元素节点则很方便。在这里插入图片描述

  • 基于元素节点树的遍历(遍历元素节点树):
  1. parentElement //返回当前元素的父元素节点(IE9以下不兼容)
  2. children // 返回当前元素的元素子节点
  3. firstElementChild //返回的是第一个元素子节点(IE9以下不兼容)
  4. lastElementChild //返回的是最后一个元素子节点(IE9以下不兼容)
  5. nextElementSibling //返回的是后一个兄弟元素节点(IE9以下不兼容)
  6. previousElementSibling //返回的是前一个兄弟元素节点(IE9以下不兼容)

注意:
这些获取节点的方式,返回值要么是一个特定的节点,要么是一个集合HTMLCollection,这个节点的集合是一个类数组。

HTML中的 attribute 和 JavaScript中的 property
attribute

attribute是HTML标签中定义的属性(修改html属性,会改变html结构),它的值只能是字符串。
attribute 有三个方法:setAttribute() , getAttribute(), removeAttribute()

property

property是JavaScript为元素对象定义的属性(修改对象属性,不会体现到html结构中)
property 属性可以看作 DOM 对象的键值对,用点操作符修改。它也可以和其他的 JavaScript 对象一样添加自定义的属性以及方法。property 的值可以是任何的数据类型,对大小写敏感。

attributeproperty 共同拥有的属性

虽然Attribute和Property定义的属性分别在不同层面上,但是有以下几个属性是共享的:
id class lang dir title

<div id="div" class="class" lang="lang" dir="dir" title="title" user="user" >
 var ele = document.getElementById('id');console.log(ele.getAttribute('id'))    // idconsole.log(ele.getAttribute('class')) // classconsole.log(ele.getAttribute('lang'))  // langconsole.log(ele.getAttribute('dir'))   // ltrconsole.log(ele.getAttribute('title')) // titleconsole.log(ele.getAttribute('user'))  // userele.user1= 'user1'console.log(ele.id)                    // idconsole.log(ele.className)             // classconsole.log(ele.lang)                  // langconsole.log(ele.dir)                   // ltrconsole.log(ele.title)                 // titleconsole.log(ele.user1)                 // userconsole.log(ele.user)                  // undefinedconsole.log(ele.getAttribute('user1')) // null

自定义的 property 不会出现在 html 代码中,只存在 js 中。因此,ele.getAttribute(‘user1’) 结果为:null

html 标签的5个标准特性:id,title,lang,dir,className(在DOM中以property方式操作这几个特性会同步到html标签中)。所以即使在html中没有指定id、title等,也会默认赋予一个空串,通过property属性(点操作符)可以访问。
而除此之外在html中设置的其他属性是不能通过Property访问到的(除了attribute特有的属性)。因此,ele.user 结果为:undefined

注意:
有一些比较特殊的情况:

- input 元素的 value
var input1 = document.getElementById('input1'); // 获取id为'input1' 的input元素
input1.setAttribute('value', 'test');  // 用setAttribute()方法设置value属性为'test'
console.log(input1.value); // testa.value = 'change';   // property方式设置value
console.log(a.getAttribute('value')); // test

用点操作符修改 value 值,并不会同步到 attribute 上;但是通过 setAttribute 修改属性值,会同步到 property 上。

- 表单
<input type='radio' checked='checked' id='radio'>
<script>var radio = document.getElementById('radio');console.log(radio.getAttribute('checked')); // 'check'console.log(radio.checked); // true
</script>

一些表单元素,对于这些特殊的 attribute 节点,只要存在该节点,对应的 property 就为true,disabled 类似

- href
<a href='a.html' id='web'> </a>
<script>var radio = document.getElementById('web');console.log(web.getAttribute('href')); // 'a.html' console.log(web.href); // 绝对路径
</script>

attribute 取得是相对路径;property 取得是绝对路径。

建议:
尽量使用property,因为property可能会在js的一些机制中避免DOM的重新渲染,而attribute一旦改了html结构,则一定会引起DOM重新渲染。

以下两种情况用attribute:

  1. 自定义 attribute 标签,因为它不能同步到 property 上。
  2. 访问内置的 html 标签的 attribute,如 input 的 value(可以用来检验 value 值是否改变)

DOM 结构操作

  • 新增/插入节点
  • 获取子元素列表,获取父元素
  • 删除子元素

各种DOM操作,请读者自由发挥,耍起来哟~~
一定要记得多敲敲!!!在这里插入图片描述
示例:主要代码如下

<div id="div1" class="container"><p id="p1">一段文字 1</p><p>一段文字 2</p><p>一段文字 3</p>
</div>
<div id="div2"><img src="https://img-blog.csdnimg.cn/20200201200740869.jpg"/>
</div>
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
// 插入节点
div1.appendChild(newP)// 移动节点
const p1 = document.getElementById('p1')
div2.appendChild(p1)// 获取父元素
console.log( p1.parentNode )// 获取子元素列表
const div1ChildNodes = div1.childNodes
console.log( div1.childNodes )
const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => {if (child.nodeType === 1) {return true}return false
})
console.log('div1ChildNodesP', div1ChildNodesP)// 删除子元素
div1.removeChild( div1ChildNodesP[0] )

DOM 性能

DOM 操作非常“昂贵”,避免频繁的DOM操作。

  • 对DOM 查询做缓存
// 不缓存 DOM 查询结果
for (let = 0; i < document.getElementsByTagName('p').length; i++) {// 每次循环,都会计算 length, 频繁进行 DOM 查询
}// 缓存 DOM 查询结果
const pList = document.getElementsByTagName('p')
const length = pList.length
for (let i = 0; i < length; i++) {// 缓存 length, 只进行一次 DOM 查询
}
  • 将频繁操作改为一次性操作
const list = document.getElementById('list')// 创建一个文档片段,此时还没有插入到 DOM 结构中
const frag = document.createDocumentFragment()for (let i  = 0; i < 20; i++) {const li = document.createElement('li')li.innerHTML = `List item ${i}`// 先插入文档片段中frag.appendChild(li)
}// 都完成之后,再统一插入到 DOM 结构中
list.appendChild(frag)console.log(list)
复习回顾在这里插入图片描述
  • DOM 是哪种数据结构
    • 树(DOM树)
  • DOM 操作的常用API
    • DOM 节点操作
    • DOM 结构操作
    • attribute 和 property 操作
  • attribute 和 property 的区别
    • attribute:修改html属性,会改变html结构
    • property:修改对象属性,不会体现到html结构中
    • 两者都有可能引起DOM重新渲染
  • 一次性插入多个DOM节点,考虑性能
    • 你可以翻上去再瞧瞧

http://chatgpt.dhexx.cn/article/LWCoYVPL.shtml

相关文章

JavaScript中DOM操作

Web前端基础修炼 HTML基本标签详解与运行截图 CSS基本操作详解及截图演示 JavaScript基础(ECMAScript) JavaScript中DOM操作 JavaScript中BOM操作 目录 DOM介绍 获取元素 操作元素 节点操作 DOM介绍 JavaScript一共包括三部分&#xff0c;分别是ECMAScript也就是Jav…

Dom操作的性能优化

在 开发过程中&#xff0c;或多或少都会遇到要操作dom的情况&#xff0c;而dom操作多多少少都会耗费一些性能&#xff0c;那今天我们就一起来看看在操作dom的时候有哪些性能优化方式吧&#xff1a; 1.选择性能更好的获取dom元素的方法 首先&#xff0c;我们一起来看看&#xf…

常见的DOM操作有哪些

这里是修真院前端小课堂&#xff0c;本篇分析的主题是 【常见的DOM操作有哪些】 这里是修真院前端小课堂&#xff0c;每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能&…

js中Dom操作

简单的Dom获取 什么是Dom操作&#xff1f; 1.DOM使一个"使程序"和"脚本"有能力的"动态地访问"和"更新文档内容结构"&#xff0c;以及"样式"的平台和语言中立的接口. 2.在HTML和JavaScript的学习中&#xff0c;DOM操作可谓时…

TypeScript Dom操作

文章目录 介绍获取元素类型断言获取多个DOM元素操作文本内容操作样式操作事件 介绍 DOM 是浏览器提供的&#xff08;浏览器特有)&#xff0c;专门用来操作网页内容的一些JS对象(API) 通过DOM操作&#xff0c;可以让Js/Ts控制页面&#xff08;(HTML)内容&#xff0c;让页面“动…

JavaScript DOM操作

文章目录 JavaScript DOM操作DOM操作元素DOM查询修改元素内容/属性获取元素节点 DOM的增删改 DOM操作CSS内联样式获得当前正在显示的样式 DOM的事件操作事件对象事件对象的属性 事件的冒泡和事件的委托事件冒泡事件委派事件的传播事件的绑定 JavaScript DOM操作 DOM操作元素 …

DOM的操作

一、DOM的操作 1、复制节点 cloneNode(deep) 参数deep是boolean类型&#xff0c;true/false true&#xff1a;表示深度复制&#xff08;将节点及其子节点都进行复制&#xff09; --- 深拷贝 false&#xff1a;表示浅复制&#xff08;只复制节点而不复制子节点&#xff09; ----…

DOM(操作)

DOM 1 作用和分类 作用&#xff1a;使用 JS 去操作 html 和浏览器 分类&#xff1a;DOM(文档对象模型)、BOM(浏览 器对象模型) DOM 是用来呈现以及与任意HTML 或 XML文档交互的API简单说&#xff1a;DOM 是浏览器提供的一套专门用来 操作网页内容 的功能DOM的作用&am…

13前端学习之WebAPI(三):节点操作、事件高级、DOM事件流、事件委托冒泡

文章目录 一、节点操作:1. 删除节点:1.2. 案例&#xff1a;删除留言 2. 赋值(克隆)节点:3. 案例:动态生成表格:3.1 案例分析:3.2 实现: 4. 创建元素的三种方式:4.1 区别:4.2 innerTHML和createElement效率对比: 5. DOM的核心总结:5.1 创建:5.2 增加:5.3 删除:5.4 改:5.5 查&…

DOM操作

今天开始进入JS的核心操作 DOM&#xff0c;DOM操作其实很简单&#xff0c;就是增删改查这几个操作&#xff0c;先看一下思维导图&#xff1a; 1.增加操作 1.新建&#xff1a; fn creatElement(标签名) 创建元素节点 fn setAttribute&#xff08;name,value&#xff09;直接设置…

JS中DOM元素的操作

一、DOM元素的获取 1&#xff09;document.getElementsByClassName ( “class”) 返回集 htmlcollection ,用法和数组一致 说明: class为DOM元素上class属性的值 2&#xff09;document.getElementById( “id” ) 功能:返回对拥有指定ID的第一个对象的引用 返回值: DOM对象 说明…

java锁结构之无锁偏向锁轻量级锁重量级锁

一、对象的本质&#xff08;锁在对象中的体现&#xff09; 1.1、对象的结构 对象由多部分构成的&#xff0c;对象头、属性字段、补齐字段等。补齐字段是指如果对象总大小不是4字节的整数倍&#xff0c;会填充上一段内存地址是之成为4的整数倍。 其中&#xff0c;对象头在对象…

简单理解重量级锁、轻量级锁、偏向锁

全文使用synchronized来说明。 synchronized给对象上锁&#xff0c;先上偏向锁&#xff0c;在上轻量级锁&#xff0c;最后上重量级锁。上什么锁&#xff0c;是jvm根据竞争程度自行变换的。 重量级锁 计算机操作系统本有Monitor对象&#xff0c;称为管程。在java里面看不到此对…

synchronized锁升级之偏向锁

目录 一、什么是偏向锁&#xff1f; 二、偏向锁原理 三、偏向锁演示 四、偏向锁的处理流程 五、偏向锁的撤销 六、偏向锁的好处 一、什么是偏向锁&#xff1f; HotSpot作者经过研究实践发现&#xff0c;在大多数情况下&#xff0c;锁不仅不存在多线程竞争&#xff0c;而…

Java无锁、偏向锁、轻量级锁、重量级锁,锁升级过程

2. 锁 2.1 无锁 Java对象刚创建时还没有任何线程来竞争&#xff0c;说明该对象处于无锁状态&#xff08;无线程竞争它&#xff09;&#xff0c;这时偏向锁标识位是0&#xff0c;锁状态是01 。 2.2 偏向锁 偏向锁是指一段同步代码一直被同一个线程所访问&#xff0c;那么该…

偏向锁的获取和撤销详解

Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗&#xff0c;引入了偏向锁和轻量级锁&#xff1b;在Java SE 1.6 中&#xff0c;锁共有4种状态&#xff0c;级别从底到高依次是&#xff1a;无锁状态、偏向锁状态、轻量级锁和重量级锁状态&#xff0c;这几种状态会随着竞争情况…

一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁

文章目录 前言一、无锁二、偏向锁三、轻量级锁&#xff08;自选锁&#xff09;四、重量级锁锁升级场景 前言 JDK1.6为了减少获得锁和释放锁所带来的性能消耗&#xff0c;引入了“偏向锁”和“轻量级锁”&#xff0c;所以在JDK1.6里锁一共有四种状态&#xff0c;无锁状态&#x…

synchronized的偏向锁、轻量级锁和重量级锁

文章目录 Java对象头偏向锁批量重偏向批量撤销 轻量级锁重量级锁Monitor 原理 Java对象头 普通对象 Mark Word在64 位虚拟机中的结构为 Mark Word后三&#xff08;两&#xff09;位表示 001&#xff1a;无锁状态101&#xff1a; 偏向锁00&#xff1a; 轻量级锁10&#xff1a…

Java synchronized偏向锁、轻量级锁、重量级锁

简介 synchronized锁共有偏向锁、轻量级锁、重量级锁三种类型&#xff0c;而这三种类型的加锁方式都是相同的&#xff0c;写代码时不用考虑加哪种锁。使用锁时对象首先会变为偏向锁状态&#xff0c;当有其它线程获取锁时会升级为轻量级锁&#xff08;没有竞争锁&#xff09;&am…

java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

之前做过一个测试&#xff0c;详情见这篇文章《多线程 1操作的几种实现方式&#xff0c;及效率对比》&#xff0c;当时对这个测试结果很疑惑&#xff0c;反复执行过多次&#xff0c;发现结果是一样的: 1. 单线程下synchronized效率最高&#xff08;当时感觉它的效率应该是最差…