addEventListener()第三个参数一定是useCapture吗?
addEventListener()第三个参数一定是useCapture吗? 回答:不一定是useCapture,还可以是一个对象
那么这个对象可以是什么呢 ?读完文章相信我们就能回答上这个问题了。
概述
方法是将指定的监听器注册到EventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素Element,Document和Window或者任何其他支持事件的对象(比如XMLHttpRequest)。 addEventListener()的工作原理是将实现EventListener的函数或对象添加到调用他的EventTarget上的指定事件类型的事件侦听器列表中。
语法
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture);
target.addEventListener(type, listener, useCapture, wantUntrusted); / /Gecko/Mozilla only
参数
type 表示监听事件类型的字符串。 listener 当所监听的事件列星触发时,会接收到一个通知对象,listener必须是一个实现了EventListener接口的对象,或者是一个函数
btnDom.addEventListener('click', function(event) {
alert('btn clicked 1');
});
btnDom.addEventListener('click', {
handleEvent: function(event) {
alert('btn clicked 2')
}
});
option(可选) 一个指定有关listener属性的可选参数对象,可用的选项如下
参数 | 值类型 | 描述 |
---|---|---|
capture | Boolean | 该类型的事件捕获阶段传播到该EventTarget时触发 |
once | Boolean | 添加后最多只调用一次,如果为true。listener会在被调用之后自动移除 |
passive | Boolean | 设置为true时,标识listener永远不会调用preventDefault(),如果listener仍然调用了这个函数,客户端将会忽略并抛出一个控制台警告 |
signal | AbortSignal | 该AbortSignal的abort() 方法被调用时,监听器会被移除 |
mozSystemGroup | Boolean | 只在 XBL 或者Firefox chrom中使用,true表示listener被添加到system group中 |
useCapture Boolean,在dom树中,注册了listener元素,是否要犹豫他下面的EventTarget,调用该listener。当设置为true是,沿着dom树向上冒泡的事件,不会触发listener,当一个元素嵌套了另一个元素,并且两个元素对同一事件才注册了一个处理函数是,所发生的事件冒泡和事件捕获是两种不同的事件传播方式,事件传播模式决定了元素一那个顺序接受事件。事件流和Event order
wantsUntrusted 如果为true,则时间处理程序会就会接受网页自定义的事件,此参数只适用于Gecko(chrome的默认值是true,其他常规网页的默认值是false),主要用于附加组件的代码和浏览器本身
用法说明
事件监听回调
事件监听器可以被指定为毁掉函数或实现EventListener的对象,其handleEvent()方法用做回调函数。 回调函数本身具有与handleEvent()方法相同的参数和返回值;也就是说,回调函数接受一个参数,一个基于Event的对象,描述已发生的事件,并且它不返回任何内容。
function eventHandler(event) {
if(event.type === 'fullscreenchange') {
}
else {}
}
option支持的安全检测
在旧版本的DOM的规定中,addEventListener()
的第三个参数是一个布尔值标识在捕获阶段调用事件处理程序。 随着时间的推移,很明显需要更多的选项,与其在方法之中添加更多的参数(传递可选值将会变得异常复杂),倒不如把第三个参数改为一个包含了各种属性的对象,这些属性的值用来被配置删除事件侦听器的过程。
因为旧版本的浏览器(以及一些相对不算古老的)仍然假定第三个参数是布尔值,我们需要编写一些代码来有效的处理这种情况。
例如下面
let passiveSupported = false;
try {
let options = Object.definedProperty({}, 'passice', {
get: function() {
passiveSupported = true;
}
});
window.addEventListener('test', null, options);
} catch(err) {}
示例中为passive属性创建了一个带有getter函数的options对象;getter设置为一个标识,passiveSupported被调用后会把其设为为true。这意味着如果浏览器检查options对象上的passive值时,passiveSupported将会被设置为true,否则会被保持false。然后我们调用addEventListener()去设置一个指定这些选项的事件处理器,这样如果浏览器将第三个参数认定为对象,这些选项值就会被检查。
btnDom.addEventListener(
'click',
handleMouseUp,
passiveSupported ? { passive: true} : false
)
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>addEventListener</title>
<style>
.outer, .middle, .inner1, .inner2 {
display:block;
width:520px;
padding:15px;
margin:15px;
text-decoration:none;
}
.outer{
border:1px solid red;
color:red;
}
.middle{
border:1px solid green;
color:green;
width:460px;
}
.inner1, .inner2{
border:1px solid purple;
color:purple;
width:400px;
}
</style>
</head>
<body>
<div class="outer">
outer, once & none-once
<div class="middle" target="_blank">
middle, capture & none-capture
<a class="inner1" href="https://www.mozilla.org" target="_blank">
inner1, passive & preventDefault(which is not allowed)
</a>
<a class="inner2" href="https://developer.mozilla.org/" target="_blank">
inner2, none-passive & preventDefault(not open new page)
</a>
</div>
</div>
<script>
let outer = document.getElementsByClassName('outer')[0];
let middle = document.getElementsByClassName('middle')[0];
let inner1 = document.getElementsByClassName('inner1')[0];
let inner2 = document.getElementsByClassName('inner2')[0];
outer.addEventListener(
'click',
function onceHandler(event){
console.log('outer, once');
},
{ once : true}
);
outer.addEventListener(
'click',
function noneOnceHandler(event) {
console.log('outer, none-once, default');
},
{ once : false }
);
middle.addEventListener(
'click',
function captureHandler(event) {
//event.stopImmediatePropagation();
console.log('middle, capture');
},
{ capture : true }
);
middle.addEventListener(
'click',
function noneCaptureHandler(event) {
console.log('middle, none-capture, default');
},
{ capture : false }
);
inner1.addEventListener(
'click',
function passiveHandler(event) {
// Unable to preventDefault inside passive event listener invocation.
//在调用passive事件监听器内部不能使用preventDefault
event.preventDefault();
console.log('inner1, passive, open new page');
},
{ passive : true }
);
inner2.addEventListener(
'click',
function passiveHandler(event) {
// Unable to preventDefault inside passive event listener invocation.
//在调用passive事件监听器内部不能使用preventDefault
event.preventDefault();
console.log('inner1, passive, open new page');
},
{ passive : false }
);
</script>
</body>
</html>
转载自:https://juejin.cn/post/7093135883708301348