saber 酱的抱枕

Fly me to the moon

10/6
2020
学习

JavaScript 点击页面空白处,关闭浮窗/弹框/菜单

假设有一个页面,上面黄色部分是一个浮窗。我们需要用 JavaScript 实现:点击页面其他部分时关闭这个浮窗。

要点在于区分用户点击的是浮窗还是其他部分。

假设我们将浮窗的元素保存为变量 a,那么如下代码即可实现此效果:

a.addEventListener('click', (e) => {
  const ev = e || window.event
  ev.stopPropagation()
})

document.addEventListener('click', () => {
  a.style.display === 'none'
})

做了两件事:

  1. 点击浮窗时(包括点击浮窗内的元素),阻止事件冒泡;
  2. 点击 document 时,隐藏浮窗。

为什么这样可以区分点击了哪里呢?因为达到了这样的效果:

  1. 点击浮窗时,不会触发 document 的点击事件;
  2. 点击浮窗之外的元素,才会触发 document 的点击事件。

这涉及到 JavaScript 的事件触发机制。如果有没想明白的同学可以继续往下看。

当一个事件发生时,塔首先会进入捕获阶段(Event Capturing),自外部向内部传播。传播到最内部之后,再进入冒泡阶段(Event Bubbling),向外部传播:

上面代码中监听事件都是监听的冒泡部分,所以我们只看冒泡部分:

当点击浮窗时,我们阻断了冒泡的传播

所以此时不会传播到 document 上,在 document 上也监听不到这个事件。

当点击浮窗之外的元素时,由于我们没有阻断事件的传播,所以事件会冒泡到 document 上,被监听到:

所以最后的效果就是,当你在 document 上监听到点击事件时,一定是浮窗之外的元素触发的。此时就可以关闭这浮窗了。

JavaScript 点击页面空白处,关闭浮窗/弹框/菜单