在Vue组件中使用DOMElement.addEventListener捕获前面的事件

时间:2017-05-23 20:30:00

标签: vuejs2 addeventlistener

我有一个Vue组件,在其created生命周期方法中为文档添加了一个事件监听器,以捕获根$el之外的任何点击。我们称之为Popup

当我点击召唤并安装上述Popup的元素时,会立即捕获文档点击事件。

这是一个简化代码的jsfiddle:https://jsfiddle.net/awei01/5vuqjcxd/

而且,相比之下,这是一个正确绑定点击事件的纯js版本:https://jsfiddle.net/awei01/qzqku0w9/

作为交叉参考,以下是vue论坛帖子:https://forum.vuejs.org/t/document-addeventlistener-captures-a-click-preceding-listeners-creation/11558

任何见解都表示赞赏。

1 个答案:

答案 0 :(得分:1)

归功于Vue核心团队成员LinusBorg

需要setTimeout

https://forum.vuejs.org/t/document-addeventlistener-captures-a-click-preceding-listeners-creation/11558

以下是实施setTimeout的工作示例:https://jsfiddle.net/awei01/ovr9sr6k/

英文说明:

  1. 点击事件发生并进入capture阶段。 parent Vue组件处理此事件。
  2. parent组件设置内部$data标志以显示popup模块
  3. popup模块被实例化并挂载。在created函数中,附加document.addEventListener事件。
  4. 点击事件capture阶段完成并开始冒泡DOM。
  5. 点击事件现在由document捕获,因为我们刚刚添加了事件监听器。它会触发回调,看起来没有发生任何事情。
  6. 解决方案:

    1. 点击事件发生并进入capture阶段。 parent Vue组件处理此事件。
    2. parent组件设置内部$data标志以显示popup模块
    3. popup模块被实例化并挂载。在created函数中,将document.addEventListener附加到setTimeout函数中,以便在点击事件完全完成后附加它。
    4. 点击事件capture阶段完成并开始冒泡DOM。
    5. 活动的bubble阶段完成
    6. setTimeout内的回调现在正在运行,而文档现在会收听点击次数
    7. 将捕获任何随后冒出document的点击次数。