# 事件冒泡与事件捕获
3 min read
Table of Contents
事件流描述的是从页面中接受事件的顺序,主要是事件冒泡和事件捕获。
事件冒泡
事件冒泡(event bubbling),即事件开始时由最具体的元素接收,然后逐级向上传播到 window 对象。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <div id="myDiv">Click</div> </body></html>当点击了 div 元素,事件传播 div -> body -> html -> Document -> window。
事件捕获
事件捕获(event capturing),是由事件从 window 对象开始接收事件,然后逐级向下传播到具体元素。
如上代码,点击掉了 div 元素,事件传播 window -> Document -> html -> body -> div。
DOM 事件流
三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。
新增事件和删除事件的操作:addEventListener(type, listener [, options]) 和 removeEventListener(type, listener [, options])
事件委托
事件委托就是利用事件的冒泡原理,把元素的响应事件代理到其父辈元素上,可以减少循环绑定。
<!-- 普通的html列表标签 --><ul id="list"> <li>item 1</li> <li>item 2</li> <li>item 3</li></ul>/* 普通的遍历元素注册事件监听 */var items = document.getElementsByTagName('li')for (var i = 0; i < items.length; i++) { items[i].addEventListener('click', function (e) { e.target.parentNode.removeChild(e.target) })}/* 事件委托 */var list = document.getElementById('list')list.addEventListener('click', function (e) { list.removeChild(e.target)})event 对象的属性和方法
| 属性/方法 | 类型 | 说明 |
|---|---|---|
| target | Element | 事件的目标 |
| currentTarget | Element | 其事件处理程序当前正在处理事件的那么元素,即触发事件的元素 |
| preventDefault | Function | 取消事件的默认行为 |
| stopPropagation | Function | 取消事件的进一步捕获或冒泡 |
target 与 currentTarget
<div class="container"> <button>Click me</button></div>const div = document.querySelector('.container')div.addEventListener('click', (e) => { console.log('target', e.target) console.log('currentTarget', e.currentTarget)})当我们点击按钮的时候,我们可以看到不同的输出结果
target <button>Click me</button>currentTarget <div class="container">...</div>- targt 是触发事件的根元素
- currentTarget 是处理该事件的元素
不会触发冒泡的事件
- scroll
- blur
- focus
- mouseentter
- mouseleave
其他
React 的事件体系就是基于事件委托建立的,其中有很大的部分都是处理不同事件之间的差异性的,对于这些不会冒泡的事件,React 也进行了处理。
React 的事件系统可以参考上一篇的《React事件系统》
参考链接
- 《JavaScript 高级程序设计(第 3 版)》
- React 中的事件委托
- Event target v currentTarget