我有一个Firefox扩展程序,用于修改用户正在查看的页面内容。作为该过程的一部分,扩展需要触发扩展本身添加到页面源的自定义事件。我将参数传递给该自定义事件时遇到困难。我做错了什么?
脚本块插入页面的head
:
document.addEventListener("show-my-overlay", EX_ShowOverlay, false, false, true);
function EX_ShowOverlay(e) {
alert('Parameter: ' + e.index);
// ...
}
扩展程序中的代码:
var event = content.document.createEvent("Events");
event.initEvent("show-my-overlay", true, true);
event['index'] = 123;
content.document.dispatchEvent(event);
事件成功触发,但e.index
未定义。
我设法通过在页面上创建一个元素然后让事件处理程序找到元素并读取其属性来使它工作,但它并不优雅。我想在没有元素的情况下这样做。
修改
我还尝试使用CustomEvent
触发事件,但它在处理程序中抛出异常:
var event = new CustomEvent('show-my-overlay', { detail: { index: 123 } });
content.document.dispatchEvent(event);
function EX_ShowOverlay(e) {
alert('Parameter: ' + e.detail.index);
// ...
}
Permission denied to access property 'detail'
答案 0 :(得分:2)
您无法跨安全边界访问“expandos”(在本机原型对象上定义的其他属性)。在这种情况下,安全边界介于完全特权的chrome(附加组件)代码和非特权网站代码之间。
所以你需要使用“标准”的东西传递数据。 CustomEvent
的东西可以做,但是你的代码是错误的。您必须正确调用构造函数或initCustomEvent()
:
var event = new CustomEvent('show-my-overlay', { detail: { index: 123 } });
content.document.dispatchEvent(event);
另一种选择是the postMessage
API。
答案 1 :(得分:2)
OP使用postMessage
解决了他们的问题。对于我们这些真正需要使用CustomEvent
解决问题的人(能够指定消息类型很有用),这里的答案是:
Firefox不允许页面脚本通过CustomEvent
访问内容脚本发送的详细信息对象中的任何内容,除非您首先使用特定于Firefox的{{1}将事件详细信息克隆到文档中功能。
以下可以解决从扩展程序向页面发送对象的问题:
cloneInto()
Mozilla docs在var clonedDetail = cloneInto({ index: 123 }, document.defaultView);
var event = new CustomEvent('show-my-overlay', { detail: clonedDetail });
document.dispatchEvent(event);
上有更详细的信息。