由附加脚本无法接收的函数/回调发送的内容脚本事件

时间:2012-04-22 15:37:27

标签: javascript firefox-addon firefox-addon-sdk

我正在使用context-menu项单击来显示一个对话框(使用JQuery / Bootstrap),该对话框允许用户通过AJAX将他们选择的文本提交到Web服务(这一切都完美无缺)。提交后,我打算显示附加SDK notification以表示“感谢您的提交”。

现在,我知道我需要从内容脚本向附加脚本发送消息以显示通知,但是当从回调函数发送时,我的消息不会到达。

我的附加代码(摘录):

var pageMod = require("page-mod");
pageMod.PageMod({
  include: ['*'],
  contentScriptWhen: "end",
  contentScriptFile: [ data.url("js/content.js") ],

  onAttach: function onAttach( worker, mod) {
    worker.port.on("submittedNotif", function(msg) {
        console.log('Hello');
        notifications.notify({ ... });
    })
  }
});

内容脚本如下。我已经指出了消息到达的情况,以及消息到达的位置。

// Handle the context-menu Item's click and show the dialog

self.on("click", function(node,data) {
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
    showDialog( 'DialogName', function (response) { /* Do stuff */ });
})

self.port.emit("submittedNotif", '*** Arrives OK ***');

function showDialog( str, response) {
    // Dialog stuff
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
}

我被告知self是一个全局对象,所以我当然不应该将它作为参数传递。我不清楚尝试通过self.port.emit发送的内容应该根据内容脚本中的使用位置而有所不同。例如,我不知道任何线程问题。也许这是我的JavaScript知识的一个空白,但任何人都可以告诉我我做错了什么?

2 个答案:

答案 0 :(得分:1)

我不清楚点击事件会来自哪个

self.on('click')

你需要做的是将点击处理程序绑定到页面的DOM中的某些东西,这些东西会被点击,例如你提到的对话框。查看这个相当简单的构建器示例,通过在显示确认对话框时发出事件来执行此操作:

https://builder.addons.mozilla.org/addon/1049875/latest/

main.js:

var data = require("self").data;
var notifications = require("notifications");
var pageMod = require("page-mod");
pageMod.PageMod({
  include: ['*'],
  contentScriptWhen: "end",
  contentScriptFile: [ data.url("jquery.js"), data.url("content.js") ],

  onAttach: function onAttach( worker, mod) {
    worker.port.on("submittedNotif", function(msg) {
        notifications.notify({
            title: 'Notification!',
            text: 'This is the notification: '+ msg
        });
    })
  }
});

content.js:

$(function() {
    if(confirm("send submitted event?")) {
        self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
        showDialog( 'DialogName', function (response) { /* Do stuff */ });
    }
});


//self.port.emit("submittedNotif", '*** Arrives OK ***');

function showDialog( str, response) {
    // Dialog stuff
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
}

答案 1 :(得分:0)

我解决了自己的问题。这是我学习的方式和方法。

首先,内容脚本和context-menu项目的点击处理程序:

self.on("click", function(node,data) {
    self.postMessage({ kind:'submittedNotif', msg: 'Just clicked'})
    showDialog( self, 'DialogName', function (response) { /* Do stuff */ });
})

现在,旧self.port.emit让我无处可去,但切换到self.postMessage并在onMessage()项目中添加context-menu最终会给我我想要的事件。

我现在也将self传递给showDialog()方法[这违背了我所说的self全局......?!],作为参数'eventHandler':

function showDialog( eventHandler, str, response) {
    // Dialog stuff
    eventHandler.postMessage({ kind:'submittedNotif', msg: 'Thank you for your submission'});
}

再一次,我放弃self.port.emit,切换到self.postMessage,并在传入的处理程序上调用它。

最后,notifications.notify({ ... });来电从PageMod的{​​{1}}移至菜单项onAttach()。简而言之,响应该单击而发生的所有事情现在都发生在菜单项的范围内。

现在一切正常。回想起来也许这一切似乎都很明显 - 但文档肯定是混淆而不是澄清,尤其是onMessage()port之间的区别