我正在尝试使用他们的sdk创建一个firefox插件,但我不知道如何让我的js脚本进行通信.目标是制作一个带有表格的面板,有3个复选框,选中后可以隐藏/显示活动选项卡上的某些元素.
以下是脚本:main.js:
var data = require("sdk/self").data; var painel1 = require("sdk/panel").Panel({ width: 215, height: 160, contentURL: data.url("painelDestroyer.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"), panel: painel1 }); // Attach a content script to the current active tab let worker = require("sdk/tabs").activeTab.attach({ contentScriptFile: data.url("clear.js") }); painel1.port.on("show-tag",function(tag){ worker.port.emit("show-tag", {tag:tag}); console.log("worker emited"); }); painel1.port.on("hide-tag",function(tag){ worker.port.emit("clear-tag", {tag:tag}); console.log("worker emited"); });
painel.js:
$("#imgD").click(function() { if ($(this).is(":checked")) { panel.port.emit("clear-tag","img"); console.log("panel emited"); } else { panel.port.emit("show-tag","img"); console.log("panel emited"); } }); $("#aD").click(function() { if ($(this).is(":checked")) { panel.port.emit("clear-tag","a"); console.log("panel emited"); } else { panel.port.emit("show-tag","a"); console.log("panel emited"); } }); $("#iframeD").click(function() { if ($(this).is(":checked")) { panel.port.emit("clear-tag","iframe"); console.log("panel emited"); } else { panel.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发送消息到main.js然后发送到clean.js,但是我该怎么做?如何在clean.js或painel.js中收到消息?我一直认为self.port在painel.js中不存在.
问题是您尝试从模块脚本而不是内容脚本访问和修改页面内容.没有window
或document
在模块脚本的范围内,如文档中所述.因此,jQuery $
将无法在您的附加脚本中使用任何内容.
您需要将attach
另一个内容脚本添加到当前选项卡.然后,您可以通过向其工作端口发送消息来显示/隐藏页面上的元素,类似于您在附加模块脚本和面板脚本之间进行通信的方式.
// Attach a content script to the current active tab let worker = require("sdk/tabs").activeTab.attach({ contentScriptFile: data.url("tabscript.js") }); // Send it a message worker.port.emit("show-tag", tag);
然后,您可以将tagHide
函数移动到活动选项卡的内容脚本,并在其中放置一些端口侦听器.这样,附加脚本可以发出一些消息并tagHide
适当地调用内容脚本.
注意:您最好使用page-mod
而不是附加到选项卡.最后,您可能不希望每次用户导航到其他页面时手动附加脚本,因此全局PageMod(include: "*"
)是一个简单的解决方案.不过,在转发邮件时,您需要确保定位当前标签的工作人员.因此,您需要跟踪所有这些工作人员并在工作人员分离时进行清理(使用worker.on('detach', callback)
.最后,您应该遍历所有当前连接的工作人员并找到附加到当前活动选项卡页面的工作人员(通过比较每个worker.tab
到tabs.activeTab
).
或者,您可以直接将命令作为JavaScript直接注入选项卡页面,如将内容脚本附加到选项卡中所示.我发现这非常难看,并且它不允许您在内容脚本中保留一些状态(跨命令保留的页面上的变量),您可能需要更复杂的脚本.
更新1:至于您更新的问题,SDK指南中的答案非常详细.您只需要使用self.port.on
以下命令绑定侦听器:
self.port.on('show-tag', function(tag) { tagHide(tag, false); }); self.port.on('clear-tag', function(tag) { tagHide(tag); });
另外,当加载项开始时,您当前的代码只能与当前活动的选项卡一起使用.最有可能的是,活动标签会发生变化,您需要随着时间的推移将内容脚本注入其他标签.见你如何我以前的笔记可以管理所有这些脚本的工人.