简单的DOM的相关总结
DOM 全称是Document object model
,翻译为,文档对象模型,是 HTML 和 XML 文档的编程接口。
把 HTML 中各个标签定义出的元素以对象的形式包装起来,然后可通过 JS 对标签进行增删改查。
DOM 结构以树的形态存在,最小单位是节点。
DOM的节点类型
节点类型主要有:
- Document:指这份文件,也就是这份 HTML 档的开端。当浏览器载入 HTML 文档, 它就会成为 Document 对 象。
- Element:指 HTML 文件内的各个标签,像是
<div>、<span>
这样的各种 HTML 标签定义的元素 - Text:指被各个标签包起来的文字,像是
<div>就是这段文字</div>
- Attribute:指元素的特性,就是各个标签上的属性
- Comment:指文档注释
<!-- 注释 -->
DOM 的增删改查
- 增:document.createElement('span')、parent.appendChild(x)
- 删:y.parent.removeChild(y)
- 改:x.someAttr = '...'、y.parent.insertBefore(appendElement,ele)
- 查 querySelector、querySelectorAll、getElementById/ClassName/TagName
DOM 事件体系
先说下专有名词:
- 事件:在浏览器里的动作,可以是用户触发的,也可以是浏览器触发的。如
click mouseover
- 事件监听函数:也叫
事件处理程序
,是事件发生后,浏览器如何响应,其实就是用来应答事件的函数,。 - 事件流(事件的流向):事件在页面中传播的顺序
体系主要从四方面理解:
- DOM 事件流,分 3 个阶段:事件捕获阶段、目标阶段、冒泡阶段(V字形)
- 事件对象:当事件 DOM 元素中穿梭时,会触发当前元素上绑定的相应事件处理函数,此时会产生一个事件对象 event 作为处理函数的入参。其囊括了与事件有关的信息,比如由触发事件的元素、事件的类型等
- 自定义事件
- 事件代理
事件对象
e.currentTarget 和 e.target 事件对象两个属性很容易混淆,简单说下联系和区别:
- 本质上
e.currentTarget
是绑定事件的当前元素,e.target
是触发事件的元素。 - 因为有捕获和冒泡阶段,所以这两可能不一样
- 假设有个
div
,里面有一个 span 标签和 b 标签,给 div 绑定点击事件的时候,e.currentTarget
则始终是 div,但是如果点击的是span
标签,e.target
就是span
, - 重点!!!如果点击这两标签之外的但又是 div 内部的区域,
e.target
就是div
,此时和e.currentTarget
是一致的
常用的两个方法:
event.stopPropagation()
,让事件不再冒泡,将事件的影响面控制在目标元素这个范围内event.preventDefault()
,阻止浏览器的默认动作,比如点击 a 标签会跳转
自定义事件
除了浏览器的默认事件click
之类,开发者可以自己创建新事件。
比如现在有三个同级元素a b c
,点击 a 之后,想要 b 和 c 也知道 a 被点击。
那么可以创建一个clickA
事件,然后让 b 和 c 绑定这个事件,点击 a 之后就让 b 和 c 触发这个事件
看个例子:
<div> <div id="a">a</div> <div id="b">b</div> <div id="c">c</div> </div> <script> // 新建一个自定义事件 var clickA = new Event("clickA"); document.querySelector("#a").addEventListener("click", function() { // a点击之后,就是clickA事件触发的时候,但浏览器不认识它,所以感知和派发,可以自己来实现: document.querySelector("#b").dispatchEvent(clickA); document.querySelector("#c").dispatchEvent(clickA); }); document.querySelector("#b").addEventListener("clickA", () => { console.log("b"); }); document.querySelector("#b").addEventListener("clickA", () => { console.log("c"); }); </script>
事件代理
事件在冒泡阶段的时候,会将事件一层层传播,直到整个文档。而从事件对象的target
属性,可以知道传播到哪里了。
于是,利用事件的冒泡特性,可以将多个子元素的同一类型的监听逻辑,合并到父元素上通过一个监听函数来管理的行 为,就是事件代理。
通过事件代理,我们可以减少内存开销、简化注册步骤,大大提高开发效率。
<ul> <li>1</li> <li>2</li> </ul> <script> var ul = document.querySelector("ul"); ul.addEventListener("click", function(e) { // 这里点击不同的li就会输出相应的内容,e.target就是正在点击的元素 console.log(e.target.innerHTML); }); </script>