当前位置: 首页 > news >正文

很啰嗦,再次总结 DOM

DOM (文档对象模型) 详解

一、DOM 基础概念

1. 定义与作用

DOM(Document Object Model)即文档对象模型,是一种用于 HTML 和 XML 文档的编程接口。它将文档解析为一个由节点和对象组成的树状结构,允许程序和脚本动态访问、修改文档的内容、结构和样式。

2. 核心特点
  • 树形结构:DOM 将文档表示为节点树,每个节点可以有子节点。
  • 平台和语言无关:DOM 可以被任何编程语言访问,如 JavaScript、Python 等。
  • 动态交互:通过 DOM,程序可以实时改变文档的内容和结构。
3. 节点类型

DOM 树中的节点主要分为以下几种类型:

  • 元素节点(Element Node):表示 HTML 元素,如 <div><p> 等。
  • 文本节点(Text Node):表示元素内的文本内容。
  • 属性节点(Attribute Node):表示元素的属性,如 idclass 等。
  • 文档节点(Document Node):表示整个文档,是 DOM 树的根节点。
  • 注释节点(Comment Node):表示 HTML 中的注释。

二、DOM 树结构

1. 节点关系
  • 父节点(Parent Node):每个节点(除根节点外)都有一个父节点。
  • 子节点(Child Node):一个节点可以有零个或多个子节点。
  • 兄弟节点(Sibling Node):共享同一个父节点的节点互为兄弟节点。
  • 祖先节点(Ancestor Node):父节点的父节点,依此类推。
  • 后代节点(Descendant Node):子节点的子节点,依此类推。
2. 示例 HTML 与 DOM 树
<!DOCTYPE html>
<html>
<head><title>DOM 示例</title>
</head>
<body><div id="container"><h1>Hello, DOM!</h1><p class="content">这是一个 <a href="#">DOM 示例</a></p></div>
</body>
</html>

对应的简化 DOM 树结构:

Document
└── html (Element)├── head (Element)│   └── title (Element)│       └── "DOM 示例" (Text)└── body (Element)└── div (Element, id="container")├── h1 (Element)│   └── "Hello, DOM!" (Text)└── p (Element, class="content")├── "这是一个 " (Text)└── a (Element, href="#")└── "DOM 示例" (Text)└── "。" (Text)

三、JavaScript 中的 DOM 操作

1. 访问 DOM 元素
通过 ID 访问
const element = document.getElementById('container');
通过标签名访问
const paragraphs = document.getElementsByTagName('p');
// 返回 HTMLCollection 对象
通过类名访问
const elements = document.getElementsByClassName('content');
// 返回 HTMLCollection 对象
通过选择器访问
const element = document.querySelector('#container p');
// 返回匹配的第一个元素const elements = document.querySelectorAll('p.content');
// 返回 NodeList 对象
2. 操作元素内容
修改文本内容
const heading = document.querySelector('h1');
heading.textContent = '新标题';
修改 HTML 内容
const container = document.getElementById('container');
container.innerHTML = '<p>新内容</p>';
3. 操作元素属性
获取属性值
const link = document.querySelector('a');
const href = link.getAttribute('href');
设置属性值
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
直接访问属性
link.href = 'https://example.com';
link.target = '_blank';
4. 操作元素样式
内联样式
const element = document.getElementById('container');
element.style.backgroundColor = 'lightblue';
element.style.width = '500px';
类操作
element.classList.add('active');
element.classList.remove('hidden');
element.classList.toggle('highlight');
5. 创建和修改元素
创建新元素
const newDiv = document.createElement('div');
newDiv.textContent = '新创建的元素';
添加子元素
const parent = document.getElementById('container');
parent.appendChild(newDiv);
插入元素
const referenceElement = document.querySelector('p');
parent.insertBefore(newDiv, referenceElement);
删除元素
parent.removeChild(referenceElement);
替换元素
const newElement = document.createElement('span');
parent.replaceChild(newElement, referenceElement);
6. 事件处理
事件监听
const button = document.getElementById('myButton');
button.addEventListener('click', function() {alert('按钮被点击了!');
});
事件对象
button.addEventListener('click', function(event) {console.log('事件类型:', event.type);console.log('触发元素:', event.target);
});
事件冒泡与捕获
  • 冒泡(Bubbling):事件从触发元素向上传播到父元素。
  • 捕获(Capturing):事件从文档根向下传播到触发元素。
// 使用捕获阶段
element.addEventListener('click', function() {// ...
}, true);
阻止事件传播
event.stopPropagation();
阻止默认行为
event.preventDefault();

四、DOM 性能优化

1. 减少 DOM 操作
批量修改
// 低效
const list = document.getElementById('myList');
for (let i = 0; i < 1000; i++) {const item = document.createElement('li');item.textContent = `Item ${i}`;list.appendChild(item);
}// 高效
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {const item = document.createElement('li');item.textContent = `Item ${i}`;fragment.appendChild(item);
}
list.appendChild(fragment);
2. 使用事件委托
// 为大量按钮添加事件
document.getElementById('buttonContainer').addEventListener('click', function(event) {if (event.target.tagName === 'BUTTON') {console.log('按钮被点击:', event.target.textContent);}
});
3. 缓存 DOM 引用
// 低效
for (let i = 0; i < 1000; i++) {document.getElementById('myElement').style.left = i + 'px';
}// 高效
const element = document.getElementById('myElement');
for (let i = 0; i < 1000; i++) {element.style.left = i + 'px';
}
4. 避免频繁重排和重绘
重排(Reflow)

当 DOM 的变化影响了元素的布局信息时,浏览器需要重新计算元素的布局,将其安放在界面中的正确位置。

重绘(Repaint)

当一个元素的外观发生改变,但没有影响到布局信息时,浏览器会将新样式应用到元素上。

优化建议
  • 批量修改样式
  • 使用 documentFragment
  • 避免频繁读取布局信息
  • 使用 transform 和 opacity 进行动画

五、DOM 与 XML

1. XML DOM

DOM 最初是为 XML 设计的,同样适用于 HTML。XML DOM 提供了与 HTML DOM 类似的 API 来操作 XML 文档。

2. XML 解析示例
const xmlText = '<book><title>JavaScript DOM</title><author>John Doe</author></book>';
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlText, 'text/xml');const title = xmlDoc.querySelector('title').textContent;
console.log('书名:', title);

六、DOM 标准

1. DOM 级别
  • DOM Level 1:1998 年发布,定义了基本的 DOM 结构和操作。
  • DOM Level 2:2000 年发布,增加了事件模型、样式、遍历和范围等模块。
  • DOM Level 3:2004 年发布,增加了文档验证、加载和保存等功能。
  • DOM Living Standard:W3C 持续更新的 DOM 标准。
2. DOM API 分类
  • 核心 DOM:通用的 DOM 操作接口。
  • HTML DOM:专门针对 HTML 的扩展。
  • SVG DOM:针对 SVG 图形的扩展。
  • XML DOM:针对 XML 文档的扩展。

七、高级 DOM 技术

1. 节点遍历
const element = document.getElementById('container');
let node = element.firstChild;while (node) {console.log('节点类型:', node.nodeType);console.log('节点内容:', node.textContent);node = node.nextSibling;
}
2. 范围(Range)
const range = document.createRange();
range.selectNode(document.getElementById('myElement'));// 复制范围内容
const fragment = range.cloneContents();
document.body.appendChild(fragment);
3. Mutation Observer

监听 DOM 变化的现代 API。

const observer = new MutationObserver((mutations) => {mutations.forEach((mutation) => {console.log('DOM 变化类型:', mutation.type);});
});const options = {childList: true,attributes: true,subtree: true
};observer.observe(document.body, options);

八、DOM 与性能监控

1. 使用 Performance API
// 测量 DOM 操作时间
console.time('dom操作');// DOM 操作
const element = document.createElement('div');
document.body.appendChild(element);console.timeEnd('dom操作');
2. Chrome DevTools 性能分析
  • 使用 Performance 面板记录和分析页面性能。
  • 关注 Layout(重排)和 Paint(重绘)事件。

九、DOM 安全问题

1. XSS 攻击
  • 恶意代码通过未过滤的用户输入注入到 DOM 中。
  • 防范措施:对用户输入进行过滤和转义。
2. 安全编码实践
// 不安全
const userInput = '<script>alert("XSS");</script>';
document.getElementById('output').innerHTML = userInput;// 安全
const textNode = document.createTextNode(userInput);
document.getElementById('output').appendChild(textNode);

十、DOM 的未来发展

1. Web Components
  • 使用 Shadow DOM 创建封装的组件。
  • 减少全局命名空间污染。
2. 虚拟 DOM
  • React、Vue 等框架使用虚拟 DOM 提高性能。
  • 减少直接操作真实 DOM 的频率。

通过深入理解 DOM,开发者可以更高效地操作网页内容,优化性能,并创建出交互性更强的 Web 应用。

相关文章:

  • 历史数据分析——中证白酒
  • 阿里云服务器跑模型教程
  • 数学复习笔记 17
  • 数据结构*优先级队列(堆)
  • 剖析智能指针shared_ptr实现原理
  • 【软考 McCabe度量法】
  • 并发学习之synchronized,JVM内存图,线程基础知识
  • Hi3516DV500刷写固件
  • 392. Is Subsequence
  • linux线程基础
  • 摄影构图小节
  • Linux线程同步信号量
  • Vue-键盘事件
  • React学习(二)-变量
  • Centos7.9同步外网yum源至内网
  • 2025最新的软件测试面试大全(含答案+文档)
  • Java获取淘宝拍立淘API接口的详细指南
  • DeepSeek 大模型部署全指南:常见问题、优化策略与实战解决方案
  • 精益数据分析(64/126):移情阶段的用户触达策略——从社交平台到精准访谈
  • 开源项目实战学习之YOLO11:12.2 ultralytics-models-sam-decoders.py源码分析
  • 竞彩湃|英超欧冠悬念持续,纽卡斯尔诺丁汉能否拿分?
  • 人民网:激发博物馆创新活力,让“过去”拥有“未来”
  • 新任重庆市垫江县委副书记刘振已任县政府党组书记
  • 从近200件文物文献里,回望光华大学建校百年
  • 国家卫生健康委通报关于肖某引发舆情事件调查处置进展情况
  • 马上评|让查重回归促进学术规范的本意