我在将 JavaScript 数组传递给附加组件时遇到问题,我正在写 Add-on Builder .
为了交流,我使用事件并使用数组发送事件,但附加组件(内容脚本)获取的是对象,而不是数组。
这是事件:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script type="application/x-javascript">
$(function() {
$(window).bind('Runner-PageEvent', function(event) {
console.log('PAGE: Reakcja na Runner-PageEvent na stronie');
});
$(window).bind('RunnerResult', function(event) {
console.log('PAGE: Result is ' + event.originalEvent.detail.Result);
//// PROBLEM!!!
console.log('PAGE: Should be array: ' + event.originalEvent.detail.array); // firebug shows object
});
$(window).bind('Runner-DetectCallback', function(event) {
console.log('PAGE: Reakcja na Runner-DetectCallback na stronie');
$('#browser-detection').text('Extension detected').css('background-color', 'green').css('color', 'white');
});
var event = new CustomEvent("Runner-Detect", {});
window.dispatchEvent(event);
console.log('PAGE: Runner-Detect sent');
});
function CallExtension() {
var event = new CustomEvent("Runner-PageEvent", { detail : {
a: "messageA",
b: "messageB",
c: "messageC",
d: "messageD",
arrayA: ["a", "b", "c", "d"],
arrayB: [0, "info", "info2", 3]
}});
window.dispatchEvent(event);
console.log('PAGE: CALL EXTENSION clicked');
}
</script>
</head>
<body>
<div id="browser-detection" style="background-color: red">No extension</div>
<br/>
Run extension: <button onclick="CallExtension()">Run!</button>
</body>
</html>
Firebug 将事件显示为具有一个属性 detail.tab
的对象作为具有四个项目的数组。
内容脚本接收一个对象e
,其中e.detail.tab
是一个对象(但应该是一个数组)。
window.addEventListener(
'eventname',
function(e) {
// console.log(e.detail.tab.length); -> produce an error on console (Ctrl+Shift+J)
// console.log(e.detail.tab[0]); -> as above
for(var x in e.detail.tab){
console.log(x);
console.log(e.detail.tab[x]);
}
self.port.emit('SendToExtension', e.detail);
}
);
不知道是Add-on Builder有问题还是我哪里做错了?
请帮忙!
最佳答案
CustomEvent()
中似乎存在错误将信息传入和传出沙箱 ( XPCNativeWrapper )。它在某些情况下不正确地序列化 CustomEventInit.detail
值,并且在第一个这样的实例之后,根本无法传递 detail
值——暗示某种内存/状态腐败正在发生。
以下请引用本测试页:jsbin.com/ajegib/1 .
在“测试”模式下安装或运行此 Firefox 附加组件:CustomEvent data_ across the sandbox .
请注意,测试网页和扩展的内容脚本都有如下代码:
window.addEventListener ("EventWithArrayData", function (zEvent) { console.log ( "Event detail: ", zEvent.detail, Array.isArray (zEvent.detail) ); } ); var zEvent = new CustomEvent ("EventWithArrayData", {"detail": [5,6,7] } ); window.dispatchEvent (zEvent)
打开 both Firebug 的控制台,以及 Firefox 错误控制台(CtrlShift J) 以观察结果,因为发送了带有
detail
数组值的自定义事件。 (您可以按普通数组数据按钮,发送它们。)
应该发生什么:
网页和扩展程序都应该将来自两个事件的数据视为一个数组。
Firebug 控制台应该显示:
**The Normal button was pressed.** In web page (Normal) from page: [1, 2, 3] true In web page (Normal) to page: [5, 6, 7] true
FF 错误控制台应该显示:
info: In Content Script (Normal) from page: 1,2,3 true info: In Content Script (Normal) to page: 5,6,7 true
发生了什么:
关于第一个事件:
Firebug 控制台显示:
**The Normal button was pressed.** In web page (Normal) from page: [1, 2, 3] true In web page (Normal) to page: {0: 5, 1: 6, 2: 7} false
FF 错误 控制台显示:
info: In Content Script (Normal) from page: [object Object] false info: In Content Script (Normal) to page: 5,6,7 true
关于所有后续事件:
Firebug 控制台显示:
**The Normal button was pressed.** In web page (Normal) from page: [1, 2, 3] true In web page (Normal) to page: null false
FF 错误 控制台显示:
info: In Content Script (Normal) from page: [object Object] false info: In Content Script (Normal) to page: null false
观察:
- 在所有情况下,网页 都能正确地看到它自己的事件发送的数组数据。它看到一个数组。
- 但是,扩展看到的是一个类似数组的对象。
- 从扩展程序发送的数组数据在第一次传递时正确显示给扩展程序,但在所有后续尝试中都为空。
- 从扩展程序发送的数组数据显示为页面的对象,然后根本不显示(
null
)!
解决方法:
两者都是the CustomEvent documentation和 the DOM Standard说明 eventInitDict.detail
可以是任何类型。但对于通过附加沙箱发送的事件,情况显然并非如此。
好像没有Firefox bugs为了这。也许我们应该打开一个。
无论如何,似乎可行的解决方法是对我们使用 CustomEvent()
发送的数据进行 JSON 编码。
像这样发送:
var detailVal = JSON.stringify ( [1, 2, 3] );
var zEvent = new CustomEvent ("EventWithJSON_Data",
{"detail": detailVal }
);
window.dispatchEvent (zEvent)
这样接收:
window.addEventListener ("EventWithJSON_Data", function (zEvent) {
var datArray = JSON.parse (zEvent.detail);
console.log (
"JSON data: ", datArray, Array.isArray (datArray)
);
} );
您可以通过按 JSON 编码数组数据 按钮在测试页 + 扩展程序上看到这一点。 (一定要先刷新页面以清除上面讨论的损坏。)
关于javascript - Firefox 扩展将 Javascript 数组作为对象发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12727733/