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

JS中DOM详解【十大点】

JavaScript DOM 详解

JavaScript 中的 DOM(文档对象模型)是前端开发的重要知识点。它通过对象结构来表示 HTML 或 XML 文档,并提供对其内容进行操作的接口。本文将详细介绍 DOM 的基础知识、常用操作和事件处理等内容,确保全面且深入。

1. DOM 概述

文档对象模型(DOM, Document Object Model) 是浏览器对 HTML 和 XML 文档的编程接口。DOM 将整个文档作为树结构,其中的每个节点代表文档的一部分,如元素、属性或文本。

2. DOM 树结构

DOM 将 HTML 文档建模为树结构,HTML 标签作为树中的节点,标签嵌套关系成为节点之间的父子关系。

<!DOCTYPE html>
<html><head><title>Sample Document</title></head><body><div><p>Hello World</p></div></body>
</html>

这个简单 HTML 文档对应的 DOM 树结构:

  • document (根节点)
    • html
      • head
        • title -> 文本节点:Sample Document
      • body
        • div
          • p -> 文本节点:Hello World

3. DOM 节点类型

DOM 树中的每个部分都是节点,节点根据其功能分为不同类型:

  • Element 节点(元素节点):表示 HTML 元素(如 <div>, <p> 等)。
  • Text 节点:表示元素或属性中的文本(如 Hello World)。
  • Attribute 节点:表示元素的属性(如 <img src="image.jpg"> 中的 src 属性)。
  • Comment 节点:表示注释内容(如 <!-- This is a comment -->)。

DOM 节点类型对应的数值标识符:

  • 1 - Element
  • 3 - Text
  • 8 - Comment
  • 9 - Document

4. DOM 节点的继承树

DOM 节点具有复杂的继承关系,所有 DOM 节点都继承自 Node,但根据不同的节点类型,其继承关系有所不同。

Node├── Element│     └── HTMLElement│           ├── HTMLDivElement│           ├── HTMLParagraphElement│           └── 其他 HTML 元素├── Text├── Comment└── Document
  • Node: DOM 树中所有节点的基类,提供了操作节点的基本方法。
  • Element: 继承自 Node,所有 HTML 元素都是 Element 的实例。
  • HTMLElement: 是 Element 的子类,具体 HTML 标签的基类,如 HTMLDivElementHTMLParagraphElement 等。

5. DOM 选择器

DOM 选择器是查找和操作 DOM 节点的基础。以下是常见的选择器方法:

5.1 getElementById

根据元素的 id 属性查找对应的元素。

const element = document.getElementById('myId');
5.2 getElementsByClassName

根据类名查找所有具有该类名的元素,返回一个动态的 HTMLCollection。

const elements = document.getElementsByClassName('myClass');
5.3 getElementsByTagName

根据标签名查找所有该标签的元素,返回一个动态的 HTMLCollection。

const elements = document.getElementsByTagName('div');
5.4 querySelector

根据 CSS 选择器查找第一个匹配的元素。

const element = document.querySelector('.myClass');
5.5 querySelectorAll

根据 CSS 选择器查找所有匹配的元素,返回静态的 NodeList。

const elements = document.querySelectorAll('.myClass');

6. DOM 操作

操作 DOM 节点是前端开发中的常见任务。以下是 DOM 的基本操作示例:

6.1 创建元素

使用 document.createElement() 创建一个新的 HTML 元素节点。

const newDiv = document.createElement('div');
6.2 插入元素

使用 appendChild() 将新创建的节点插入到父节点的末尾。

const parent = document.getElementById('parent');
parent.appendChild(newDiv);
6.3 删除元素

使用 removeChild() 删除指定的子节点。

const parent = document.getElementById('parent');
const child = document.getElementById('child');
parent.removeChild(child);
6.4 替换元素

使用 replaceChild() 替换子节点。

const newChild = document.createElement('span');
parent.replaceChild(newChild, oldChild);
6.5 修改元素内容

使用 innerHTMLtextContent 修改元素的内容。

// 修改 HTML 内容
element.innerHTML = '<p>New Content</p>';// 修改纯文本内容
element.textContent = 'New Text';
6.6 遍历节点

使用 childNodes 属性遍历父节点的子节点。

const parent = document.getElementById('parent');
const children = parent.childNodes;children.forEach((child) => {console.log(child);
});

7. 常用 DOM 属性和方法

以下是常见的 DOM 属性和方法,并附带具体的使用示例:

7.1 常用属性
  • nodeName:返回节点的名称。

    console.log(element.nodeName); // 输出:DIV
    
  • nodeType:返回节点的类型。

    console.log(element.nodeType); // 输出:1(表示元素节点)
    
  • childNodes:返回包含所有子节点的 NodeList。

    const children = parent.childNodes;
    console.log(children); // NodeList
    
  • parentNode:返回父节点。

    console.log(element.parentNode); // 返回父节点
    
  • firstChildlastChild:返回第一个和最后一个子节点。

    console.log(parent.firstChild);  // 返回第一个子节点
    console.log(parent.lastChild);   // 返回最后一个子节点
    
  • nextSiblingpreviousSibling:返回下一个或上一个兄弟节点。

    console.log(element.nextSibling);  // 下一个兄弟节点
    console.log(element.previousSibling); // 上一个兄弟节点
    
7.2 常用方法
  • appendChild(node):将节点添加为最后一个子节点。

    parent.appendChild(newElement);
    
  • removeChild(node):删除指定的子节点。

    parent.removeChild(childElement);
    
  • replaceChild(newNode, oldNode):用新节点替换旧节点。

    parent.replaceChild(newElement, oldElement);
    
  • cloneNode(deep):克隆节点,deep 参数决定是否递归克隆子节点。

    const clonedElement = element.cloneNode(true);
    

8. DOM 事件

DOM 事件是网页与用户交互的核心。浏览器会在用户与页面交互时触发各种事件。

8.1 常见事件类型

以下列举了常见的事件类型:

  • 鼠标事件

    • click: 用户点击时触发。
    • dblclick: 用户双击时触发。
    • mouseover: 鼠标悬停在元素上时触发。
    • mouseout: 鼠标离开元素时触发。
    • mousemove: 鼠标在元素上移动时触发。
    • mousedown: 鼠标按下时触发。
    • mouseup: 鼠标按键释放时触发。
    • contextmenu: 右键菜单触发时。
  • 键盘事件

    • keydown: 按键被按下时触发。
    • keypress: 按键按下并字符输入时触发(已被废弃,不推荐使用)。
    • keyup: 按键释放时触发。
  • 表单事件

    • submit: 表单提交时触发。
    • change: 表单元素值改变时触发。
    • input: 用户输入时触发。
    • focus: 元素获得焦点时触发。
    • blur: 元素失去焦点时触发。
  • 窗口事件

    • resize: 窗口大小变化时触发。
    • scroll: 页面滚动时触发

  • load: 页面完全加载时触发。
8.2 事件处理方法

使用 addEventListener() 为元素绑定事件处理函数:

const button = document.getElementById('myButton');
button.addEventListener('click', () => {alert('Button clicked!');
});

还可以使用 removeEventListener() 来移除事件监听器:

button.removeEventListener('click', handleClick);

9. DOM 性能优化

在操作 DOM 时,性能是重要的考虑因素。频繁的 DOM 操作会引发重绘和重排,导致性能下降。以下是一些优化策略:

  • 减少 DOM 操作次数:将多次操作合并为一次操作。
  • 使用 DocumentFragment:在一个临时的文档片段上操作,最后一次性插入到 DOM 中。
  • 减少对布局信息的查询:避免频繁读取触发回流的属性,如 offsetHeightscrollTop
// 使用 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);

10. DOM 遍历

在处理复杂 DOM 树时,遍历所有节点是一个常见的任务。可以使用递归函数进行深度优先遍历:

function traverseDOM(node) {console.log(node);  // 处理节点// 递归遍历子节点node.childNodes.forEach(traverseDOM);
}// 调用函数,从根节点开始遍历
traverseDOM(document.documentElement);

总结

DOM 是前端开发中不可或缺的一部分。理解 DOM 的结构、常用属性和方法,以及如何高效地操作和管理它,将帮助开发者更好地构建动态网页。学习 DOM 事件处理,能使网页与用户实现交互,让网页变得更加生动。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【C++】提示并输入一个字符串,统计该字符串中字母个数、数字个数、空格个数、其他字符的个数
  • 【归纳总结】常见排序算法及其实现:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快排、归并排序
  • JavaEE-TCP协议
  • 基于x86 平台opencv的图像采集和seetaface6的性别识别功能
  • 【Docker项目实战】使用Docker部署webtop桌面版Linux环境
  • sqli-labs靶场通关攻略(36-40关)
  • 深信服上半年亏损5.92亿,营收同比降低2.3亿
  • 【软件测试】软件测试生命周期与Bug
  • 涉假率超40%!高德上找维修,你心得多大啊……
  • Vue3父组件调用子组件的方法
  • golang RSA 解密前端jsencrypt发送的数据时异常 crypto/rsa: decryption error 解决方法
  • 如何使用ssm实现社区智慧养老监护管理平台+vue
  • 24.08.28--点云图像投影参数理解;yaml_node理解
  • 【机器学习-随记】使用 Slack 和 Facebook Messenger 的消息机器人实现虚拟客服人员
  • mysql集群技术
  • 分享一款快速APP功能测试工具
  • echarts的各种常用效果展示
  • javascript数组去重/查找/插入/删除
  • opencv python Meanshift 和 Camshift
  • passportjs 源码分析
  • PHP的Ev教程三(Periodic watcher)
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • spring boot 整合mybatis 无法输出sql的问题
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 给github项目添加CI badge
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 实战|智能家居行业移动应用性能分析
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 找一份好的前端工作,起点很重要
  • - 转 Ext2.0 form使用实例
  • 【云吞铺子】性能抖动剖析(二)
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • # .NET Framework中使用命名管道进行进程间通信
  • (3)llvm ir转换过程
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (二十六)Java 数据结构
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (十二)Flink Table API
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)iOS字体
  • (转)socket Aio demo
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .Net Web项目创建比较不错的参考文章
  • .NET 事件模型教程(二)
  • .NET/C# 使用反射注册事件
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [12] 使用 CUDA 加速排序算法
  • [20190113]四校联考
  • [2021 蓝帽杯] One Pointer PHP
  • [AI 大模型] 百度 文心一言
  • [AIGC] Spring Interceptor 拦截器详解