Svelte中按钮点击时新添加的window点击事件被立即触发问题
问题原因
这是事件冒泡导致的:点击按钮时,按钮的click事件触发并执行firstClick,同时该事件会沿着DOM树向上冒泡到window对象。就在这次冒泡过程中,你给window添加了新的click监听器,这个监听器会立刻捕获到当前正在传递的点击事件,所以secondClick被直接触发了。
简单实现方法
方法1:延迟添加监听器
把window监听器的添加操作放到setTimeout中,让它在当前事件循环(包括冒泡流程)结束后再执行,这样就不会捕获到本次按钮点击的冒泡事件:
<script> const secondClick = () => { console.log(2); }; const firstClick = () => { console.log(1); setTimeout(() => { window.addEventListener("click", secondClick, {once: true}); }, 0); }; </script> <button on:click={firstClick}> btn2 </button>
方法2:用Svelte原生语法实现(推荐)
完全借助Svelte的语法和特性,不用手动操作原生事件监听,更符合框架使用习惯:
<script> let waitForWindowClick = false; const firstClick = () => { console.log(1); waitForWindowClick = true; }; const secondClick = () => { console.log(2); waitForWindowClick = false; }; </script> <button on:click={firstClick}> btn2 </button> {#if waitForWindowClick} <svelte:window on:click|once={secondClick} /> {/if}
方法3:阻止按钮事件冒泡(谨慎使用)
如果不需要按钮的点击事件向上冒泡,可以在按钮点击时阻止事件传递,避免后续添加的window监听器捕获到本次事件:
<script> const secondClick = () => { console.log(2); }; const firstClick = (event) => { console.log(1); event.stopPropagation(); window.addEventListener("click", secondClick, {once: true}); }; </script> <button on:click={firstClick}> btn2 </button>
注意:这种方式会影响页面上其他依赖按钮点击冒泡的逻辑,需根据实际场景选择。
内容的提问来源于stack exchange,提问作者Mero
相关产品推荐
相关产品推荐

