如何阻止浏览器扩展劫持keydown事件,提升自定义监听器优先级
目前浏览器的事件系统中,没有直接标记事件监听器优先级的API,事件触发顺序主要由两个因素决定:
- 事件阶段(捕获阶段先于冒泡阶段)
- 监听器的注册顺序(同阶段下先注册的先执行)
你当前已经使用了window.addEventListener("keydown", handler, true),也就是在捕获阶段触发监听器,但仍被扩展劫持,大概率是因为该扩展的监听器也在捕获阶段,且注册时间比你的更早。
针对你的场景,可尝试以下几种解决方法:
在监听器中立即阻止事件传播
在你的handler函数开头调用event.stopImmediatePropagation(),这样能阻止同阶段后续注册的监听器触发。但这个方法生效的前提是你的监听器能先于扩展的监听器执行。尽可能早地注册监听器
如果你的脚本能在页面加载的最早期(比如<head>标签内同步加载,或在DOMContentLoaded事件触发前完成注册),就能抢在扩展脚本之前完成监听器注册,这样在捕获阶段你的代码会先执行,再通过stopImmediatePropagation()阻断后续事件。将监听器绑定到具体输入元素
既然用户是主动启用你的IPA键盘,你可以在启用时,将事件监听器直接绑定到当前活跃的输入元素(如document.activeElement),而非全局的window。因为事件捕获是从外层到内层传播,若扩展的监听器绑定在window,而你的监听器绑定在目标输入元素的冒泡阶段,你的代码会在扩展之后执行,但可以通过event.preventDefault()阻止默认行为(如果扩展依赖默认行为或后续冒泡逻辑的话);或者绑定在目标元素的捕获阶段,即便晚于window的捕获,只要扩展没有阻止传播,你依然可以处理事件并阻断后续流程。尝试使用其他事件类型替代
部分扩展可能只劫持了keydown事件,你可以尝试监听keypress(注意部分按键不触发此事件)或input事件来处理IPA输入逻辑,避开冲突。
另外,关于“用户主动启用能否设置更高优先级”:浏览器并没有提供基于用户交互的优先级提升机制,但你可以利用用户主动启用的时机,动态调整监听器的绑定策略(比如上述绑定到具体元素的方法),来提升事件处理的优先级或避开冲突。
内容的提问来源于stack exchange,提问作者Peter R

