天时地利的迷信~
各位宝宝,最近怎么样?北京的冬天来了,好冷,幸好下了一场不大不小的雪,否则对冬天真是喜欢不起来。
事件机制
事件触发三个阶段:
- window往事件触发处传播,遇到注册的捕获事件会触发
- 传播到事件触发处时触发注册的事件
- 从事件触发处往window传播,遇到注册的冒泡事件会触发
事件触发一般会按照?的顺序进行(W3C模型)
1. 先从上往下捕获 | | | / ------------------| |--| |-----------------| outer | | | | || -------------| |--| |----------- || | inner / | | | || | | | || | 2. 到达目标元素后从下往上冒泡 | || -------------------------------- || W3C event model |-------------------------------------------
但是有一个特例:如果给body中的子节点同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行。
// 以下会先打印冒泡然后是捕获node.addEventListener( 'click', event => { console.log('冒泡') }, false)node.addEventListener( 'click', event => { console.log('捕获 ') }, true)
我们来看一下如下代码到底是怎么的结果:
var selector = document.querySelector.bind(document);selector('div.outer').addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'outer clicked! '}, true)selector('div.inner').addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'inner clicked! '}, false)document.addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'document clicked! '}, true)
当点击innner元素时,如下元素发生了:
- 点击事件开始于捕获阶段,在此阶段浏览器会在所有祖先元素上查找点击事件处理函数(从document开始)
- 结果找到了2个,分别在document和outer上面,而且这两个事件处理函数的useCapture选项为true,说明他们被注册在捕获阶段的。于是,document和outer的点击处理函数被执行
- 继续向下寻找,直到到达inner元素本身,捕获阶段就此结束。此时进入冒泡阶段,inner上的时间处理器得到执行
- 事件命中元素后开始向上冒泡,一路查找是否注册了冒泡阶段的祖先元素上的时间处理器。由于没有找到因此什么也没发生。
最后的结果是
// logdocument clicked! outer clicked! inner clicked!
我们把时间注册在冒泡阶段(addEventListener的useCapture选项为false)
var selector = document.querySelector.bind(document);selector('div.outer').addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'outer clicked! ' console.log(e);}, false)selector('div.inner').addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'inner clicked! ' console.log(e);}, false)document.addEventListener('click', (e) => { selector('p:first-of-type').textContent = 'document clicked! '}, false)
结果是:
// loginner clicked! outer clicked! document clicked!
愿我们有能力不向生活缴械投降---Lin