一、捕获和冒泡
<div class="爷爷">
<div class="爸爸">
<div class="儿子">
文字
</div>
</div>
</div>
即 .爷爷>.爸爸>.儿子,分别添加事件监听 fnYe / fnBa / fnEr。
那么如果我点击文字,三个事件监听函数的调用顺序是怎样的呢,
如果按 爷爷=>爸爸=>儿子 的调用顺序,这就是捕获,
如果按 儿子=>爸爸=>爷爷 的调用顺序,这就是冒泡,
亦即从外向内找监听函数,叫事件捕获;
从内向外找监听函数,叫事件冒泡。
另外W3C 事件模型是先捕获(先爸爸 => 儿子),再冒泡(先儿子 => 爸爸)
二、事件绑定API
xxx.addEventListener('click',fn,bool)
- 如果
bool不传或者为falsy,就让fn走冒泡,即当浏览器在冒泡阶段发现xxx有fn监听函数,就会调用fn,并提供事件信息。 - 如果
bool为true,就让fn走捕获。
三、事件委托
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件委托。
优点:
1. 省监听数,即省内存
如你要给100个按钮添加点击事件,就可以监听这100个按钮的父元素,等冒泡的时候判断target是否是这100个按钮中的一个。
2. 可以监听动态元素
如你要监听一个不存在的元素的点击事件,就可以监听父元素,等点击的时候看看是不是你要监听的元素即可。
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
})
上面代码中,click事件的监听函数定义在<ul>节点,但是实际上,它处理的是子节点<li>的click事件。