3

我正在尝试使用他们的 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");
});

痛苦.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");
    }
});

清除.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);
});

问题:我该如何进行这项工作,如何在这 3 个脚本之间进行通信?我的猜测是我必须将消息从 painel.js 发送到 main.js,然后再发送到 clean.js,但我该怎么做呢?如何在 clean.js 或 painel.js 中接收消息?我不断得到 self.port 在 painel.js 中不存在。

4

1 回答 1

5

问题是您试图从模块脚本而不是内容脚本访问和修改页面的内容。如文档中所述,没有模块脚本windowdocument在模块脚本的范围内。因此,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适当地调用内容脚本。

注意:您最好使用 apage-mod而不是附加到选项卡。最后,您可能不想在每次用户导航到不同页面时手动附加脚本,因此全局 PageMod ( include: "*") 是一个简单的解决方案。尽管如此,您仍需要确保在转发消息时以当前选项卡的工作人员为目标。因此,您需要跟踪所有这些工作人员并在工作人员分离时清理它们(使用worker.on('detach', callback)。最后,您应该遍历所有当前附加的工作人员并找到附加到当前活动选项卡页面的工作人员(通过将每个worker.tabtabs.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);
});

另一方面,您当前的代码仅在加载项启动时才与当前活动的选项卡一起使用。最有可能的是,活动选项卡会发生变化,您需要随着时间的推移将内容脚本注入其他选项卡。请参阅我之前关于如何管理所有这些脚本的工作人员的说明。

于 2013-05-28T21:12:57.727 回答