一、事件与事件流
1. 事件
事件是与浏览器或文档交互的瞬间,如点击按钮,填写表格等,它是JS与HTML之间交互的桥梁。
2. 事件流
DOM是树形结构,如果同时给父子节点都绑定事件时,当触发子节点的时候,这两个事件的发生顺序如何决定?这就涉及到事件流的概念,它描述的是页面中接受事件的顺序。
事件流有两种:
事件冒泡(Event Bubbling): 是一种从下往上的传播方式。事件最开始由最具体的元素(文档中嵌套层次最深的那个节点接受, 也就是DOM最低层的子节点), 然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点。
事件捕获(Event Capturing): 与事件冒泡相反。事件最开始由不太具体的节点最早接受事件, 而最具体的节点最后接受事件。
二、事件模型
DOM2事件模型分为3个阶段:捕获阶段-目标阶段-冒泡阶段
- 第一阶段:从window对象传导到目标节点(上层传到底层),称- 为“捕获阶段”(capture phase)。
- 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
- 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。
<div style="padding:50px;border:1px solid blue">
<button>你好</button>
</div>
<script>
let btn = document.querySelector("button")
let div = document.querySelector("div")
//true - 事件在捕获阶段执行
//false - 默认。事件在冒泡阶段执行
div.addEventListener("click",()=>{console.log(1)},true)
btn.addEventListener("click",()=>{console.log(2)},true)
div.addEventListener("click",()=>{console.log(3)},false)
btn.addEventListener("click",()=>{console.log(4)},false)
</script>
//点击button: 1,2,4,3
点击button :
捕获阶段:事件从<div>向<p>传播时,触发<div>的1事件;
目标阶段:事件从<div>到达<p>时,触发<p>的2,4事件;
冒泡阶段:事件从<p>传回<div>时,再次触发<div>的3事件。
三、事件委托
事件在冒泡过程中会上传到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件代理。
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
//currentTarget指向事件绑定的元素,而target则是指向事件触发的元素。
if (event.target.tagName.toLowerCase() === 'li') {
console.log(event.target.textContent)
}
});
</script>
参考:
https://juejin.im/post/5a94bbea5188257a6049bcc5
https://wangdoc.com/javascript/events/model.html
https://segmentfault.com/a/1190000006934031#articleHeader2