我正在尝试使用他们的sdk创建一个firefox插件,但我不知道如何使我的js脚本通信。目标是制作一个带有表格的面板,有3个复选框,选中后可以隐藏/显示活动选项卡上的某些元素。
以下是脚本:main.js:
exports.main = function() {};
var data = require("sdk/self").data;
var panel1 = require("sdk/panel").Panel({
width: 215,
height: 160,
contentURL: data.url("panelDestroyer.html"),
contentScriptFile: [data.url("jquery.js"),data.url("panel.js")]
});
require("sdk/widget").Widget({
id: "open-form-btn",
label: "Clear",
contentURL: data.url("mozico.png"),
contentScriptFile: data.url("jquery.js"),
panel: panel1
});
var tabs = require("sdk/tabs");
var tabWorkers = {};
tabs.on("ready", function(tab) {
attachTabWorker(tab);
});
for each (var tab in tabs) {
attachTabWorker(tab);
}
function attachTabWorker(tab) {
// Attach and store
var tabWorker = tabWorkers[tab.id] = tab.attach({
contentScriptFile: [data.url("clear.js"),data.url("jquery.js")]
});
// Clean up
tabWorker.on("detach", function() {
if (getTabWorker(tab) === tabWorker) {
delete tabWorkers[tab.id];
}
});
}
function getTabWorker(tab) {
return tabWorkers[tab.id];
}
function getActiveTabWorker() {
return getTabWorker(tabs.activeTab);
}
panel1.port.on("show-tag",function(tag){
getActiveTabWorker().port.emit("show-tag", tag);
console.log("worker emited");
});
panel1.port.on("clear-tag",function(tag){
getActiveTabWorker().port.emit("clear-tag", tag);
console.log("worker emited");
})
painel.js:
$("#imgD").click(function() {
if ($(this).is(":checked")) {
self.port.emit("clear-tag","img");
console.log("panel emited");
} else {
self.port.emit("show-tag","img");
console.log("panel emited");
}
});
$("#aD").click(function() {
if ($(this).is(":checked")) {
self.port.emit("clear-tag","a");
console.log("panel emited");
} else {
self.port.emit("show-tag","a");
console.log("panel emited");
}
});
$("#iframeD").click(function() {
if ($(this).is(":checked")) {
self.port.emit("clear-tag","iframe");
console.log("panel emited");
} else {
self.port.emit("show-tag","iframe");
console.log("panel emited");
}
});
clear.js:
function tagHide (tag, hide) {
$(tag).each(function() {
if (hide === false) {
$(this).css({
"visibility": "visible"
});
} else {
$(this).css({
"visibility": "hidden"
});
}
});
}
self.port.on('show-tag', function(tag) {
tagHide(tag, false);
});
self.port.on('clear-tag', function(tag) {
tagHide(tag, true);
});
为什么我一直没有在painel.js中定义self.port?
答案 0 :(得分:5)
我认为问题在于您在加载加载项时尝试附加内容脚本。
let worker = require("sdk/tabs").activeTab.attach({
contentScriptFile: data.url("clear.js")
});
我认为 activeTab
可能还没有准备就绪,只是加载了你的加载项,这通常是在Firefox启动时。也许DOM还没有完全加载,或者SDK无法正确初始化内容脚本的所有组件。
SDK文档states,在使用与内容相关的属性和方法之前,您应该等到ready
事件。我假设附加内容脚本也属于该类别,因此您可能需要将其重新编写为:
let worker = null;
require("sdk/tabs").activeTab.on("ready", function(tab) {
worker = tab.attach({
contentScriptFile: data.url("clear.js")
});
});
但这仍然不足,因为用户可能会切换标签。当您在原始 ready
上注册activeTab
侦听器时,您将不会侦听新激活的选项卡,并且不会将任何内容脚本附加到该选项卡。你需要:
ready
事件; 我很快就掀起了应该做的事情。您应该能够在getActiveTabWorker()
端口事件中使用panel
来定位正确的工作人员。它还没有经过测试,所以试一试!
const tabs = require("sdk/tabs");
let tabWorkers = {};
tabs.on("ready", function(tab) {
attachTabWorker(tab);
});
for each (let tab in tabs) {
attachTabWorker(tab);
}
function attachTabWorker(tab) {
// Attach and store
let tabWorker = tabWorkers[tab.id] = tab.attach({
contentScriptFile: data.url("clear.js")
});
// Clean up
tabWorker.on("detach", function() {
if (getTabWorker(tab) === tabWorker) {
delete tabWorkers[tab.id];
}
});
}
function getTabWorker(tab) {
return tabWorkers[tab.id];
}
function getActiveTabWorker() {
return getTabWorker(tabs.activeTab);
}
编辑:我不知道 self.port
如何定义,但我发现需要修复的更多错误。也许其中一个是间接干扰self
?
main.js
正在倾听hide-tag
,而您的小组会发出clear-tag
。使用clear-tag
。tag
而不是{tag:tag}
。data.url("jquery.js")
。contentScriptFile
添加到attachTabWorker
答案 1 :(得分:1)
我也遇到了同样的问题,然后在SO上发现了这个问题:self.port is undefined error [on mozilla add-on SDK 1.8]
问题在于HTML代码,你必须在main.js和html中调用脚本。从html中删除它,并直接在main.js中声明它将解决此错误。