为什么要写这篇文章呢?是因为在看vue官方文档时,看到了事件修饰符这一块。我们都知道vue中的事件修饰符总共有6种,包括.stop、.prevent、.capture、.once、.self、.passive。对于它们的含义和使用,我就不做描述了,可以看我的这一篇文章:vue中的事件修饰符.self、.capture和.passive
。主要是结合addEventListener去理解.capture、.once、.passive等的实现原理。
1、先看一下addEventListener的用法
element.addEventListener(event, function, useCapture);
参数说明:
- event:事件名,事件的类型 (如 “click” 或 “mousedown”)。注意:不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。
- function:事件处理函数,事件触发后调用的函数
- useCapture:布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
我们先看一下捕获和冒泡阶段的流程:
通过图中的顺序我们DOM事件是先通过捕获过程到达目标元素,触发对应的事件,然后进入冒泡过程。
我们知道有一个.capture事件修饰符,是用于在捕获阶段触发事件的,其实就是通过useCapture这个参数设置为true,然后在捕获过程中触发了这个.capture修饰符装饰的事件。
2、addEventListener新的语法
通过MDN文章的查看,我发现addEventListener有三种语法,如下:
target.addEventListener(type, listener, useCapture);
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture, wantsUntrusted ); // Gecko/Mozilla only
第一种我们在上面已经说过了,我们着重说一下第二种
target.addEventListener(type, listener, options);
type 对应 event 事件名
listener 对应 function 事件处理函数
options 可选
可用的选项如下:
- capture: Boolean,表示事件处理函数会在该类型的事件捕获阶段传播到该元素的父辈元素(如果父辈绑定了事件处理函数)时触发。 对应.capture事件修饰符
- once: Boolean,表示 事件处理函数 在添加之后最多只调用一次。如果是 true, 事件处理函数 会在其被调用之后自动移除。对应.once事件修饰符
- passive: Boolean,设置为true时,表示 事件处理函数 永远不会调用 preventDefault()。如果 事件处理函数 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。查看 使用 passive 改善的滚屏性能 了解更多。对应.passive事件修饰符
- signal:AbortSignal,该 AbortSignal 的 abort() 方法被调用时,监听器会被移除。
以capture为例看一下代码的实现:
<div>
<div id="outer">
<p id="middle">
<button id="inter">点击触发</button>
</p>
</div>
</div>
<script>
// 打印的顺序为 div元素 --- p元素 --- button元素 在捕获阶段触发所有的事件。
document.querySelector('#outer').addEventListener('click',function(){
console.log('button元素');
},true)
// 也可以写为
// document.querySelector('#outer').addEventListener('click',function(){
// console.log('button元素');
// },{capture:true})
document.querySelector('#middle').addEventListener('click',function(){
console.log('p元素')
},true)
document.querySelector('#outer').addEventListener('click',function(){
console.log('div元素')
},true)
// 打印的顺序为 div元素 --- p元素 --- button元素 在捕获阶段触发所有的事件。
</script>
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener