避免其他应用程序捕获事件

Avoid event capturing by another application

简单来说,我有这样的东西

// Adds listener to capturing phase
document.addEventListener('focusin', event => event.stopPropagation(), true); 

document.querySelector('#my_div')
    .addEventListener('focusin', event => console.log('my logic'));

第一个事件侦听器来自我无法控制的应用程序。它阻止了所有对捕获阶段的关注(并且它也在做一些我为简单起见而省略的逻辑)并关注模态 window.

我在页面上嵌入了我的应用程序(它是 Chrome 扩展的内容脚本)并希望专注于嵌入元素的输入。这是不可能的,因为所有 focusin 事件都被第一个元素侦听器捕获,并且不会将其传播到我的元素。

这个问题有解决办法吗?请注意,我不能只修复第一个侦听器,因为我无法控制它...任何想法(和肮脏的技巧 :) 都非常感谢。

问题

您的 focusin 监听器在默认的第二阶段(“冒泡”)注册,因为您没有指定 true。该站点的 focusin 侦听器在 addEventListener 中向 true 注册,因此它 运行 在第一个“捕获”阶段(当事件从 window 下降到 document 并向下移动到焦点元素)并通过使用 stopPropagation 停止进一步调度事件,因此它甚至永远不会到达您的侦听器等待的默认第二阶段。

解决方案

如上所述,捕获阶段的事件从 window 下降,因此我们可以在 window 上注册一个捕获侦听器,使其在站点 [=17] 之前 运行 =]听众:

window.addEventListener('focusin', e => {
  // For nested inputs the condition should be e.target.closest('#my_div')
  if (e.target.id === 'my_div') {
    console.log('my logic');
  }
}, true);