addEventListener的第三个参数

5,814 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

el.addEventListener(type, listener[, useCapture])
  • el:事件对象。比如,某个标签,window,document 对象等等。
  • type:事件类型,click、mouseenter 等
  • listener:事件处理函数,事件发生时,就会触发该函数运行。
  • useCapture:布尔值,规定是否是捕获型,默认为 false(冒泡)。 为true时捕获,false时冒泡。因为是可选的,往往也会省略它。

2015年底,为了扩展新的选项,因此给 addEventListener 拓展了第三个参。 ECMA规范做了修订:addEventListener() 的第三个参数可为 {} 对象。

el.addEventListener(type, listener, {
    capture: false, // === useCapture
    once: false,    // 是否设置单次监听,if true,会在调用后自动销毁listener
    passive: false  // 是否让 阻止默认行为(preventDefault()) 失效,if true, 意味着listener永远不远调用preventDefault方法
})
// 新增参数的三个属性,默认值都是 false。
  • true 的触发顺序总是在 false 之前
  • 如果多个均为 true,则外层的触发先于内层;
  • 如果多个均为 false,则内层的触发先于外层。

使用DEMO

// 直接省略第三个参数
el.removeEventListener(type, listener)
 
// 如果添加了 capture: true 的事件,则加上
el.removeEventListener(type, listener, true)
el.removeEventListener(type, listener, {passive: true})

冒泡和捕获

例如,用2个div和一个button,button在div2里面,div2在div1里面。如下图所示: image.png

给button、div1、div2、都添加了click事件,分别alert button、div1、div2。

window.onload=function(){\
    document.getElementById("btn").addEventListener("click",function () {
        alert("hello");
    });
    document.getElementById("div1").addEventListener("click",function(){
        alert("div1");
    });
    document.getElementById("div2").addEventListener("click",function(){
        alert("div2");
    });
}

那么,点击button,也相当于点击了div1和div2,那么,谁先出现呢?

冒泡从里面往外面触发事件,就是alert的顺序是 button、div2、div1。

捕获从外面往里面触发事件,就是alert的顺序是div1、div2、button。

要想冒泡,就要将每个监听事件的第三个参数设置为false,也就是默认的值。

要想捕获,就要将每个监听事件的第三个参数设置为true。

阻止冒泡

现代浏览器中事件处理的方式都默认按照事件冒泡的方式处理。 (即所有浏览器中事件都是默认先按事件冒泡的方式来处理的)

如果想用事件捕获的方式处理请使用addEventListener

阻止事件冒泡的方法(阻止事件捕获也是用这个方法):
//标准:
//阻止事件传播行为
event.stopPropagation();
//非标准:
event.cancelBubble = true;
//兼容写法:
event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;