You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js 2中如何阻止addEventListener("click")创建时立即触发

解决Vue中添加body点击监听器时立即触发的问题

问题说明

点击按钮调用addEvent为document.body添加click监听器时,doSomething会立即执行。预期效果是第一次点击仅完成监听器注册,后续点击body才触发日志输出。

原因分析

按钮的click事件会向上冒泡到document.body。当你在按钮的点击回调中为body注册监听器时,当前的点击事件仍处于冒泡阶段,刚注册的body监听器会捕获到这个冒泡事件,导致doSomething被立即触发。

解决方案

方案1:阻止按钮点击事件的冒泡

通过Vue的事件修饰符或手动阻止冒泡,让按钮的点击事件不会传递到body,避免触发刚注册的监听器:

  • 使用Vue事件修饰符:
<template>
  <div id="app">
    <button @click.stop="addEvent">add event body</button>
  </div>
</template>
  • 或在方法中手动阻止:
addEvent(event) {
  event.stopPropagation();
  document.body.addEventListener('click', this.doSomething);
}

方案2:延迟添加监听器到下一个事件循环

用setTimeout把注册监听器的操作放到当前点击事件处理完成后执行,此时冒泡事件已结束,不会触发刚注册的回调:

addEvent() {
  setTimeout(() => {
    document.body.addEventListener('click', this.doSomething);
  }, 0);
}

额外优化:避免重复添加监听器

多次点击按钮会重复注册监听器,导致后续点击body时多次触发doSomething,可以加个标志位控制:

<template>
  <div id="app">
    <button @click.stop="addEvent">add event body</button>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      isListenerAdded: false
    }
  },
  methods: {
    addEvent() {
      if (!this.isListenerAdded) {
        this.isListenerAdded = true;
        document.body.addEventListener('click', this.doSomething);
      }
    },
    doSomething() {
      console.log('click');
    },
  },
};
</script>

内容的提问来源于stack exchange,提问作者yavgz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:50:43