深入理解前端DOM:现代Web开发的基石
什么是DOM?
DOM(Document Object Model,文档对象模型)是Web开发中最重要的概念之一。它是一个跨平台、语言独立的接口,将HTML或XML文档表示为树形结构,其中每个节点都是文档的一个部分(如元素、属性或文本)。DOM提供了对文档结构和内容的编程访问方式,使开发者能够动态地读取和修改页面内容、结构和样式。
DOM的历史与发展
DOM最初是在20世纪90年代末由W3C(万维网联盟)标准化,目的是解决当时浏览器之间的兼容性问题。随着Web技术的发展,DOM也经历了多个版本的演进:
-
DOM Level 1 (1998年):提供了对HTML和XML文档的基本访问
-
DOM Level 2 (2000年):添加了事件模型、样式操作等
-
DOM Level 3 (2004年):引入了XPath、键盘事件等
-
DOM Level 4 (2015年):现代DOM标准,包含了许多新特性
DOM树结构
DOM将文档表示为节点树,其中主要包含以下几种节点类型:
-
文档节点(Document Node):整个文档的根节点
-
元素节点(Element Node):HTML标签(如
<div>
、<p>
) -
属性节点(Attribute Node):元素的属性(如
class
、id
) -
文本节点(Text Node):元素内的文本内容
-
注释节点(Comment Node):HTML注释
<!DOCTYPE html>
<html>
<head><title>DOM示例</title>
</head>
<body><div id="container"><p class="text">Hello, DOM!</p></div>
</body>
</html>
上面的HTML对应的DOM树结构大致如下:
Document
└── html├── head│ └── title│ └── "DOM示例"└── body└── div#container└── p.text└── "Hello, DOM!"
常见的DOM操作
1. 选择元素
// 通过ID获取元素
const element = document.getElementById('container');// 通过类名获取元素集合
const elements = document.getElementsByClassName('text');// 通过标签名获取元素集合
const paragraphs = document.getElementsByTagName('p');// 现代选择器方法
const element = document.querySelector('#container .text');
const elements = document.querySelectorAll('p');
2. 创建和添加元素
// 创建新元素
const newDiv = document.createElement('div');
newDiv.textContent = '我是新创建的div';// 添加到文档中
document.body.appendChild(newDiv);// 插入到特定位置
const container = document.getElementById('container');
container.insertBefore(newDiv, container.firstChild);
3. 修改元素
// 修改内容
element.textContent = '新内容';
element.innerHTML = '<strong>加粗内容</strong>';// 修改属性
element.setAttribute('class', 'new-class');
element.id = 'new-id';// 修改样式
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
4. 删除元素
const element = document.getElementById('to-remove');
element.parentNode.removeChild(element);// 现代方法
element.remove();
5. 事件处理
// 添加事件监听器
const button = document.getElementById('my-button');
button.addEventListener('click', function(event) {console.log('按钮被点击了!', event);
});// 移除事件监听器
function handleClick() {console.log('只会触发一次');button.removeEventListener('click', handleClick);
}
button.addEventListener('click', handleClick);
DOM性能优化
频繁的DOM操作会导致浏览器重绘和回流,影响页面性能。以下是一些优化建议:
-
批量操作:使用文档片段(DocumentFragment)进行批量操作
const fragment = document.createDocumentFragment(); for (let i = 0; i < 100; i++) {const div = document.createElement('div');div.textContent = `Item ${i}`;fragment.appendChild(div); } document.body.appendChild(fragment);
-
减少回流:一次性修改样式而不是多次修改
// 不好 element.style.width = '100px'; element.style.height = '200px';// 更好 element.style.cssText = 'width:100px; height:200px;';
-
事件委托:利用事件冒泡减少事件监听器数量
document.getElementById('list').addEventListener('click', function(e) {if (e.target.tagName === 'LI') {console.log('点击了列表项:', e.target.textContent);} });
-
缓存DOM查询结果:避免重复查询相同的元素
虚拟DOM
在现代前端框架(如React、Vue)中,虚拟DOM(Virtual DOM)的概念被广泛使用。虚拟DOM是真实DOM的轻量级JavaScript表示,框架通过比较虚拟DOM的变化来最小化对真实DOM的操作,从而提高性能。
虚拟DOM的工作流程:
-
应用状态变化时,创建新的虚拟DOM树
-
比较新旧虚拟DOM树(diff算法)
-
计算最小变更集
-
批量更新真实DOM
现代DOM API
近年来,DOM API也引入了一些新特性:
-
classList API:更方便的类名操作
element.classList.add('new-class'); element.classList.remove('old-class'); element.classList.toggle('active');
-
dataset属性:方便访问data-*属性
<div id="user" data-id="123" data-role="admin"></div>
const user = document.getElementById('user'); console.log(user.dataset.id); // "123"
-
MutationObserver:监听DOM变化
const observer = new MutationObserver(function(mutations) {mutations.forEach(function(mutation) {console.log('DOM发生了变化:', mutation);}); });observer.observe(document.body, {childList: true,attributes: true,subtree: true });
总结
DOM是现代Web开发的核心,理解DOM的工作原理和操作方法对于前端开发者至关重要。随着Web技术的发展,DOM API也在不断演进,提供了更强大、更高效的接口。同时,虚拟DOM等概念的引入进一步提升了Web应用的性能。掌握DOM不仅能帮助你构建交互式网页,也是学习现代前端框架的基础。
在实际开发中,应该根据项目需求选择合适的DOM操作方式,平衡开发效率和性能要求,以创建流畅的用户体验。
相关文章:
深入理解前端DOM:现代Web开发的基石
什么是DOM? DOM(Document Object Model,文档对象模型)是Web开发中最重要的概念之一。它是一个跨平台、语言独立的接口,将HTML或XML文档表示为树形结构,其中每个节点都是文档的一个部分(如元素、…...
Springboot中Controller接收参数的方式
在Spring Boot中,Controller或RestController可以通过多种方式接收客户端传递的参数,主要包括以下几种常见方式: 1. 接收路径参数(PathVariable) 从URL路径中提取参数,适用于RESTful风格的API。 示例 Re…...
从一堆数字里长出一棵树:中序 + 后序构建二叉树的递归密码
从一堆数字里长出一棵树:中序 + 后序构建二叉树的递归密码 一、写在前面:一棵树的“复活计划” 作为一个老程序员,看到「中序 + 后序重建二叉树」这种题,我内心是兴奋的。为啥?它不仅是数据结构基础的“期末大题”,更是递归分解思想的典范——简洁、优雅、极具思维训练价…...

Unity UI 性能优化终极指南 — Image篇
🎯 Unity UI 性能优化终极指南 — Image篇 🧩 Image 是什么? Image 是UGUI中最常用的基本绘制组件支持显示 Sprite,可以用于背景、按钮图标、装饰等是UI性能瓶颈的头号来源之一,直接影响Draw Call和Overdraw …...

Nginx + Tomcat 负载均衡、动静分离群集
一、 nginx 简介 Nginx 是一款轻量级的高性能 Web 服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在 BSD-like 协议下发行。其特点是占有内存少,并发能力强,在同类型的网页服务器中表现优异,常用…...
【maker-pdf 文档文字识别(包含ocr),安装使用完整教程】
测试效果还比较好,比markitdown要好 安装环境 conda create -n maker-pdf python3.12 conda activate marker-pdf pip install modelscope pip install marker-pdf -U下载模型 建议用modelscope上缓存的模型,不然下载会很慢 from modelscope import s…...

c++ algorithm
cheatsheet:https://hackingcpp.com transform 元素变换 https://blog.csdn.net/qq_44961737/article/details/146011174 #include <iostream> #include <vector> #include <algorithm>int main() {std::vector<int> a {1, 2, 3, 4, 5};…...
《前端面试题:BFC(块级格式化上下文)》
前端BFC完全指南:布局魔法与面试必备 🎋 端午安康! 各位前端探险家,端午节快乐!🥮 愿你的代码如龙舟竞渡般乘风破浪,样式如香糯粽子般完美包裹!今天我们来解锁CSS中的布局魔法——B…...
HertzBeat的告警规则如何配置?
HertzBeat配置告警规则主要有以下步骤: 配置告警阈值 1. 登录HertzBeat管理界面,点击“阈值规则”菜单,选择“新增阈值”。 2. 选择要配置告警阈值的指标对象。例如,若监控Spring Boot应用,可选择如“状态线程数”等…...

安全-JAVA开发-第一天
目标: 安装环境 了解基础架构 了解代码执行顺序 与数据库进行连接 准备: 安装 下载IDEA并下载tomcat(后续出教程) 之后新建项目 注意点如下 1.应用程序服务器选择Web开发 2.新建Tomcat的服务器配置文件 并使用 Hello…...

6月2日上午思维训练题解
好好反思一下,自己在学什么,自己怎么在做训练赛的,真有这么难吗 ????? A - Need More Arrays 题解 想尽可能多的拆出新数组的个数,只需要从原本的数组中提取出最长的一…...
高考数学易错考点01 | 临阵磨枪
文章目录 前言集合与函数不等式数列三角函数前言 本篇内容下载于网络,网络上的都是以 WORD 版本呈现,缺字缺图很不完整,没法使用,我只是做了补充和完善。有空准备进行第二次完善,添加问题解释的链接。 集合与函数 1.进行集合的交、并、补运算时,不要忘了全集和空集的特…...

【CF】Day69——⭐Codeforces Round 897 (Div. 2) D (图论 | 思维 | DFS | 环)
D. Cyclic Operations 题目: 思路: 非常好的一题 对于这题我们要学会转换和提取条件,从特殊到一般 我们可以考虑特殊情况先,即 k n 和 k 1时,对于 k 1,我们可以显然发现必须满足 b[i] i,而…...
MySQL中的字符串分割函数
MySQL中的字符串分割函数 MySQL本身没有内置的SPLIT()函数,但可以通过其他方式实现字符串分割功能。以下是几种常见的方法: 1. SUBSTRING_INDEX函数 SUBSTRING_INDEX()是MySQL中最常用的字符串分割函数,它可以根据指定的分隔符从字符串中提…...

前端八股之Vue
目录 有使用过vue吗?说说你对vue的理解 你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢 一、SPA 是什么 二、SPA 和 MPA 的区别 三、SPA 的优缺点 四、实现 SPA 五、给 SPA 做 SEO 的方式(基于 Vueÿ…...
Matlab数值计算
MATLAB数值计算 数值计算函数句柄匿名函数线性与非线性方程组求解1. \(左除运算)2. fzero3. fsolve4. roots 函数极值的求解1. fminbnd2. fmincon3. fminsearch与fminunc 数值积分1. quad / quadl2. quadgk3. integral4. trapz5. dblquad, quad2d, integ…...

谷歌地图高清卫星地图2026中文版下载|谷歌地图3D卫星高清版 V7.3.6.9796 最新免费版下载 - 前端工具导航
谷歌地图高清卫星地图2024中文版是一款非常专业的世界地图查看工具。通过使用该软件,你就可以在这里看到外太空星系、大洋峡谷等场景,通过高清的卫星地图,可以清晰查看地图、地形、3D建筑、卫星图像等信息,让你可以更轻松的探索世…...

条形进度条
组件 <template><view class"pk-detail-con"><i class"lightning" :style"{ left: line % }"></i><i class"acimgs" :style"{ left: line % }"></i><view class"progress&quo…...
悟饭游戏厅iOS版疑似流出:未测试版
网传悟饭游戏厅iOS版安装包流出,提供百度网盘/夸克网盘双渠道下载。本文客观呈现资源信息,包含文件验证数据、安装风险预警及iOS正版替代方案。苹果用户请谨慎测试,建议优先考虑官方渠道。 一、资源基本信息 1.1 文件验证数据 属性夸克网盘…...
95. Java 数字和字符串 - 操作字符串的其他方法
文章目录 95. Java 数字和字符串 - 操作字符串的其他方法一、分割字符串二、子序列与修剪三、在字符串中搜索字符和子字符串四、将字符和子字符串替换为字符串五、String 类的实际应用 —— 文件名处理示例示例:Filename 类示例:FilenameDemo 类 总结 95…...

IBM DB2分布式数据库架构
一、什么是分布式数据库架构 分布式数据库架构是现代数据库系统的重要发展方向,特别适合处理大规模数据、高并发访问和高可用性需求的应用场景。下面我们从原理、架构模式、关键技术、实现方式和常见产品几个方面来系统讲 1、分布式数据库的基本概念与原理 1. 什…...
初始化已有项目仓库,推送远程(Git)
初始化Git仓库(如果还没初始化) git init 添加并提交文件 git add . ("."表示当前项目所有文件) git commit -m “first commit” 关联远程仓库(如果还没关联) git remote add origin http://xxxxxxxx 推送代码 …...

Android Studio 向模拟器手机添加照片、视频、音乐
Android Studio 向模拟器手机添加照片、视频、音乐(其实都是一样的,只是添加到不同的文件夹),例如我们在很多程序中功能例如:选择头像,跳转到手机相册选择头像,此时相册为空,即模拟器没有图片资…...

数据结构-算法学习C++(入门)
目录 03二进制和位运算04 选择、冒泡、插入排序05 对数器06 二分搜索07 时间复杂度和空间复杂度08 算法和数据结构09 单双链表09.1单双链表及反转09.2合并链表09.2两数相加09.2分隔链表 013队列、栈、环形队列013.1队列013.2栈013.3循环队列 014栈-队列的相互转换014.1用栈实现…...
访谈 | 吴恩达全景解读 AI Agents 发展现状:多智能体、工具生态、评估体系、语音栈、Vibe Coding 及创业建议一文尽览
在最新的 LangChain Interrupt 大会上(2025),LangChain 联合创始人 & CEO Harrison Chase 与吴恩达(Andrew Ng)就 AI Agnets 的发展现状,进行了一场炉边谈话。 吴恩达回顾了与 LangChain 的渊源&#…...

连接关键点:使用 ES|QL 联接实现更丰富的可观测性洞察
作者:来自 Elastic Luca Wintergerst ES|QL 的 LOOKUP JOIN 现已进入技术预览阶段,它允许你在查询时对日志、指标和追踪进行丰富处理,无需在摄取时进行非规范化。动态添加部署、基础设施或业务上下文,减少存储占用,加速…...
Tiktok App 登录账号、密码、验证码 XOR 加密算法
抖音 App 登录账号、密码、验证码 XOR 加密算法% E9 n z, \& R1 a4 b. ^ 流程分析 登录 Tiktok APP 时,通过抓包发现账号密码是非明文传输的。 <?php// http://xxx.xx.x.x.x/tiktok/$tiktok new TikTokClient();$userId 7212597544604484614; $secUid …...

Flask + Celery 应用
目录 Flask Celery 应用项目结构1. 创建app.py2. 创建tasks.py3. 创建celery_worker.py4. 创建templates目录和index.html运行应用测试文件 Flask Celery 应用 对于Flask与Celery结合的例子,需要创建几个文件。首先安装必要的依赖: pip install flas…...

奥威BI+AI数据分析:企业数智化转型的加速器
在当今数据驱动的时代,企业对于数据分析的需求日益增长。奥威BIAI数据分析的组合,正成为众多企业数智化转型的加速器。 奥威BI以其强大的数据处理和可视化能力著称。它能够轻松接入多种数据源,实现数据的快速整合与清洗。通过内置的ETL工具&…...

python打卡day43
复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 进阶:并拆分成多个文件 找了个街头食物图像分类的数据集Popular Street Foods(其实写代码的时候就开始后悔了),原因在于&…...