事件流,阻止捕获和冒泡

176 阅读2分钟

我正在参加「掘金·启航计划」

什么是事件

JavaScript 和 HTML 之间的交互是通过事件实现的。

事件,就是文档或浏览器窗口发生的一些特定的交互瞬间。

什么是事件流

事件流描述的就是从页面中接收事件的顺序。

事件流包括三个阶段: (1)事件捕获阶段 (2)处于目标阶段 (3)事件冒泡阶段

冒泡事件

以下两种绑定事件的方法,都默认只支持冒泡阶段。

<div onclick="btnClick()">click</div>

<script>
function btnClick(){
    console.log("hello");
}
</script>

//或者
<div id="btn">
    btn
</div>
<script>
    let btn = document.getElementById("btn");
    btn.onclick=function(){
        console.log(1)
    }
</script>

捕获事件

即从document逐级向下传播到目标元素, 使用以下函数绑定事件即可开启捕获阶段。

  • addEventListener() ---添加事件侦听器
  • removeEventListener() ---删除事件侦听器

函数均有 3 个参数, 第一个参数是要处理的事件名 第二个参数是作为事件处理程序的函数 第三个参数是一个 boolean 值,默认 false 表示使用冒泡机制,true 表示使用捕获机制。

<div id="btn">点击</div>

<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",function(ev){
 console.log("hello");
},true);

</script>

event.stopPropagation

有时候我们需要点击事件不再继续向上冒泡,我们可以加上stopPropagation函数,阻止程序冒泡。

<div id="btn">点击</div>

<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",function(ev){
 console.log("hello");
 ev.stopPropagation();
},false);

</script>

大多数情况下,我们都是使用 stopPropagation() 来阻止冒泡,但其实从MDN介绍:Event 接口的 stopPropagation() 方法阻止捕获和冒泡阶段中当前事件的进一步传播。来看, stopPropagation也能阻止事件的捕获。

问卷投放内的强提醒窗口内的实践

在之前的业务开发内就使用到了stopPropagation来阻止事件的向下捕获,来实现产品的需求。

产品需求如下:

image.png

通过给body绑定只生效一次的捕获的点击事件,并使用到了stopPropagation来阻止事件的向下捕获,来实现产品的需求。

阻止向下捕获的原因: 页面上有其他很多按钮之类的东西,如果不阻止向下捕获,当第一次点击是发生在按钮上时,会导致跳转或弹窗之类我们不希望出现的东西。

伪代码如下:

document.body.addEventListener('click', function (ev) {
    // 阻止向下传播
    ev.stopPropagation();
    // 执行业务代码
    xxx
}, { once: true, capture: true })