这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
前言
在框架、工具琳琅满目的今天,很多同学可能会对 DOM 不屑一顾,但是如果你的目标是中型、大型公司的优质团队,或者是技术意识稍微强一些的小团队,你都无法在面试环节规避开面对官对 DOM 基础 和 DOM 底层原理的考察
我们首先会围绕 DOM 基础,给大家进行一轮知识点扫盲。
理解DOM
TIP ? 文档对象模型(DOM)是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。 —— MDN
DOM 的概念看似抽象,实则只是把 HTML 中各个标签定义出的元素以对象的形式包装起来。这样做的目的,就是确保开发者可以通过 JS 脚本来操作 HTML。
DOM树解析
DOM结构以树的形态存在。在了解这棵树之前,我们首先应该认知的是树中的最小单元——节点。在 DOM 中,每个元素都是一个节点,节点类型细数起来可以有很多种,
- Document
每个载入浏览器的HTML文档都会成为 Document 对象。
- Element
Element 就是指 HTML 文件内的各个标签,像是 <div>
、<p>
这样的各种 HTML 标签定义的元素都属于 Element类型。
- Text
Text 就是指被各个标签包起来的文字,举个例子:
<span>哈哈哈</span>
复制代码
这里的“哈哈哈”就是这个 Element 的 Text
- Attribute
Attribute 类型表示元素的特性。从技术角度讲,这里的特性就是说各个标签里的属性
DOM操作方法
- 查找DOM节点
- getElementId // 按照id查询
- getElementsByTagName // 按照标签名查询
- getElementsByClassName // 按照类名查询
- querySelectorAll // 匹配指定 CSS 选择器的所有元素
复制代码
- 创建DOM节点
- createElement // 创建新节点
- createAttribute // 创建新的属性节点
- createTextNode // 创建新的文本节点
- setAttribute // 为一个元素创建一个新的属性
复制代码
- 删除DOM节点
- removeChild // 删除节点
复制代码
- 修改DOM节点
- innerHTML // 改变元素内容
- setAttribute 改变 HTML 属性
- insertBefore 插入前面
- replaceChild 替换子元素
复制代码
DOM事件体系
W3C 标准约定了一个事件的传播过程要经过以下三个阶段:
1. 事件捕获阶段
2. 目标阶段
3. 事件冒泡阶段
当事件被触发时,首先经历的是一个捕获过程:事件会从最外层的元素开始“穿梭”,逐层“穿梭”到最内层元素。这个穿梭过程会持续到事件抵达它目标的元素(也就是真正触发这个事件的元素)为止。此时事件流就切换到了“目标阶段”——事件被目标元素所接收。然后事件会被“回弹”,进入到冒泡阶段——它会沿着来时的路“逆流而上”,一层一层再走回去。
事件对象
- currentTarget
事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口。
- target
件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口
- preventDefault
通知 Web 浏览器不要执行与事件关联的默认动作
- stopPropagation
这个方法用于终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。
DOM自定义事件
- addEventListener
addEventListener() 方法用于向指定元素添加事件句柄。
document.getElementById("myBtn").addEventListener("click", function(){\
document.getElementById("demo").innerHTML = "Hello 青莲使者";
});
复制代码
target.addEventListener(type, listener, useCapture);
addEventListener 当参数useCapture
设为true时,沿着DOM树向上冒泡的事件,不会触发listener,useCapture
默认为 false,即为捕获
DOM事件应用
- 事件代理
概述:根据捕获与冒泡, 如果我们有许多以类似方式处理的元素,那么就不必为每个元素都分配一个事件处理程序 —— 而是将单个处理程序放在它们的共同祖先上。
优点:
- 减少内存的使用(减少函数的使用)
- 可以监听动态元素
<ul id="test">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
</ul>
复制代码
我们若要给其中的每个<li>
标签都加上一个点击事件。
var parent = document.getElementsByClassName('test')[0];
parent.addEventListener('click',function (event) {
console.log("触发事件的元素");
console.log(event.target);//点击的某一sibling
console.log("绑定事件的元素");
console.log(event.currentTarget);//parent
})
复制代码