一、引入:
对于以下代码
<div class="爷爷">
<div class="爸爸">
<div class="儿子">文字</div>
</div>
</div>
给这三个盒子都添加事件监听
问
- 点击文字,算不算点击儿子?
- 点击文字,算不算点击爸爸?
- 点击文字,算不算点击爷爷?
都算
那么他们的顺序是什么呢。
在捕获阶段,爷爷->爸爸->儿子
在冒泡阶段,儿子->爸爸->爷爷
二、DOM 事件机制
捕获与冒泡
上述过程发生了什么,为什么点击文字,就算把三个div全部点击了呢。
DOM 事件机制主要有 2 个阶段,分别是:捕获阶段和冒泡阶段
先执行捕获阶段,再执行冒泡阶段
比如刚才说的点击事件,执行的顺序就是
- 先是捕获阶段:爷爷->爸爸->儿子
- 接着是冒泡阶段:儿子->爸爸->爷爷
只要添加了时间监听,就会按照上面的顺序执行。
事件监听函数是addEventListener('click', fn, bool)
如果不穿bool的值或者bool值为false,fn函数就只在冒泡阶段执行
如果bool的值是true,那么fn函数就在捕获阶段执行。
取消冒泡
捕获不可以取消,但是冒泡可以取消,e.propagation()就可
但是有一些事件不可以取消冒泡,比如 scroll 事件,具体可以在 MDN 上查询
target 和 currentTarget 的区别
target:监听用户操作的元素
currentTarget:程序员监听的元素
<div><span>内容</span></div>
加入程序员监听的是div,用户能看见的就是内容,用户点击内容,
事件e.target就是span,而e.currentTarget就是div
三、事件委托
先来一个应用场景:我们要给 100 个按钮添加点击事件,怎么办?最笨的办法:直接给 100 个按钮都 addEventListener有了事件委托后:监听这 100 个按钮的爸爸,等冒泡的时候,判断 target 是不是这 100 个按钮中的一个
场景二:我们要监听目前不存在的元素的点击事件,咋办?有了事件委托:监听祖先,等到冒泡时ÿ