Angular中键盘事件preventDefault失效,页面滚动无法阻止求助
解决上下箭头按键阻止页面滚动无效的问题
刚看到你的问题,我之前做类似的表格键盘导航时也踩过这个坑!问题出在事件触发的时机上:你监听的是keyup事件,但这个事件是在浏览器已经完成了默认行为(比如页面滚动)之后才触发的,所以你在keyup里调用preventDefault()根本拦不住滚动——动作都已经做完了,再阻止还有啥用😅
下面给你几个可行的解决方案:
方案1:改用keydown事件(最直接有效)
keydown是在浏览器执行默认行为之前触发的,这时候调用preventDefault()就能直接阻止页面滚动。修改你的代码如下:
@HostListener('window:keydown', ['$event']) keyEvent(event: KeyboardEvent) { // 先判断模态框是否关闭,再处理箭头键 if (!this.isOpen) { if (event.keyCode === KEY_CODE.DOWN_ARROW) { event.preventDefault(); this.keyboardRowChange(1); } else if (event.keyCode === KEY_CODE.UP_ARROW) { event.preventDefault(); this.keyboardRowChange(-1); } } }
另外提个小建议:现在keyCode已经被标准废弃了,现代浏览器更推荐用event.key来判断,代码会更清晰兼容:
// 替换keyCode判断逻辑 if (event.key === 'ArrowDown') { event.preventDefault(); this.keyboardRowChange(1); } else if (event.key === 'ArrowUp') { event.preventDefault(); this.keyboardRowChange(-1); }
方案2:拆分事件逻辑(如果必须保留keyup)
如果你因为某些业务逻辑必须用keyup来处理行切换,可以把「阻止默认滚动」和「行切换」拆到两个事件里:
- 用
keydown阻止浏览器的滚动行为 - 用
keyup执行你的行切换逻辑
代码示例:
// 拦截keydown阻止页面滚动 @HostListener('window:keydown', ['$event']) preventScroll(event: KeyboardEvent) { if (!this.isOpen) { const isArrowKey = event.keyCode === KEY_CODE.DOWN_ARROW || event.keyCode === KEY_CODE.UP_ARROW; if (isArrowKey) event.preventDefault(); } } // 用keyup处理表格行切换 @HostListener('window:keyup', ['$event']) handleRowChange(event: KeyboardEvent) { if (!this.isOpen) { if (event.keyCode === KEY_CODE.DOWN_ARROW) { this.keyboardRowChange(1); } else if (event.keyCode === KEY_CODE.UP_ARROW) { this.keyboardRowChange(-1); } } }
额外排查点
如果上面的方法还是没用,你可以检查一下:
- 页面上有没有其他元素(比如表格、滚动容器)也监听了箭头键事件,并且调用了
stopPropagation(),导致你的事件监听器没拿到事件 - 确认
this.isOpen的状态是否正确,会不会在按键时模态框其实是打开状态,导致preventDefault()没被执行
内容的提问来源于stack exchange,提问作者Zachscs
相关产品推荐
相关产品推荐

