在 Chrome 扩展内容脚本中可以这样做:
const myTarget = new EventTarget()
myTarget.addEventListener('test', () => console.log('test1'))
myTarget.dispatchEvent(new Event('test'))
但这在 Firefox 中不起作用,因为在 Firefox 中
this !== window
。相反,Firefox 有 this === globalThis
,由于某种原因,某些标准 Web API(例如 globalThis['EventTarget']
中的 EventTarget)无法工作,而 window['EventTarget']
却可以工作。
因此,这意味着能够使用各种标准 Web API(例如 EventTarget),我需要通过 Window 来调用它们
window['EventTarget']
,尽管它在 Chrome 中运行良好。或者使用 delete globalThis['EventTarget']
删除 EventTarget 也会使其回退到 window['EvenTarget']
。我认为这两种解决方案都不可接受。
我该如何以理智的方式处理这个问题?
示例:
const { log } = console
log(EventTarget === EventTarget)
log(EventTarget === window['EventTarget'])
log(EventTarget === globalThis['EventTarget'])
log(EventTarget === self['EventTarget'])
const test1 = new EventTarget()
const test2 = new window['EventTarget']()
const test3 = new globalThis['EventTarget']()
test1.addEventListener('test', () => log('test1'))
test2.addEventListener('test', () => log('test2'))
test3.addEventListener('test', () => log('test3'))
test1.dispatchEvent(new Event('test'))
test2.dispatchEvent(new Event('test'))
test3.dispatchEvent(new Event('test'))
将登录 Firefox 附加内容脚本:
true
false
true
false
test2
在 Chrome 扩展内容脚本中:
true
true
true
true
test1
test2
test3
Firefox 版本:128(最新)
Firefox 清单版本:v2
Chrome 清单版本:v3
结论是,正如 @woxxom 提到的,这是 Firefox 中另一个十年前从未得到修复的错误。无需通过我们自己编码来重新发明标准 Web API,只需:
globalThis['EventTarget'] = window['EventTarget']
或
delete globalThis['EventTarget']
仅适用于 Firefox,尽管它很难看。