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
相关产品推荐
相关产品推荐

