避免其他应用程序捕获事件
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);
简单来说,我有这样的东西
// 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);