如何在JavaScript keydown事件冒泡中仅触发最后一个事件?
解决多次绑定keydown监听器导致重复触发的问题
你遇到的根本问题不是事件冒泡,而是每次signature变化时,你的useEffect都会给window新增一个keydown事件监听器,但没有清理旧的。时间久了,窗口上就绑定了好几个一模一样的处理函数,按下Ctrl+S时这些函数会全部执行,才会出现“累积事件一次性触发”的情况。
解决方法很简单:给useEffect加上清理函数,每次重新渲染前移除旧的监听器,确保同一时刻只有一个监听器生效。
修改后的代码如下:
useEffect(() => { // 把事件处理函数单独抽出来,方便后续移除 const handleKeyDown = (event) => { if (event.ctrlKey && event.key === "s") { const saveBtn = document.getElementsByClassName("flex-none align-middle mb-5").item(0)?.firstChild; if (saveBtn && !saveBtn.disabled) { Save(); } event.preventDefault(); } }; window.addEventListener("keydown", handleKeyDown); // 清理函数:在组件卸载或依赖变化时移除监听器 return () => { window.removeEventListener("keydown", handleKeyDown); }; }, [signature]);
额外优化了两处:
- 用可选链
?.避免DOM元素不存在时报错 - 把条件判断写得更严谨,防止意外调用
Save
另外补充:你之前提到的事件冒泡(事件传播)是指事件从触发元素向上传递到父元素的过程,和你现在遇到的重复触发完全是两回事,别混淆啦。
内容的提问来源于stack exchange,提问作者BubbaFett
相关产品推荐
相关产品推荐

