4

我一直在研究与页面模块通信并遇到问题的上下文菜单。

只要我不刷新页面,我就可以通过右键单击向视图中的页面/选项卡发送通信。当我刷新页面时,会创建一个新的工作人员,并且上下文菜单无法与工作人员通信。

我现在有两个相同的工人,但就像旧的工人已经过期了。这意味着 onMessage: 中的这个循环不起作用,因为它选择了第一个工人。

for (index = 0; index < workers.length; index += 1) {
    if (workers[index].tab.index === tabs.activeTab.index) {
    workers[index].port.emit("rightClick", string, ss.storage.product);
    }
}

我一直希望在刷新时删除旧工人,但似乎没有选择这样做。我是否从根本上错过了处理工人的一些事情?

我收到的错误是:错误:该页面当前处于隐藏状态,在再次可见之前无法使用。

这与就工人而言,我现在正在同一选项卡中查看新页面这一事实一致。我认为 worker.on('detach', function(){}) 应该处理这个问题,但似乎这只是在关闭选项卡时。

任何意见,将不胜感激。

稍作休息后添加OK 我决定使用其他地方推荐的 detachWorker 函数进行分离。我把它放在我的 pageMod 对象的顶部,如下所示

// Clean up duplicate worker
for (index in workers) {
    if(workers[index].url === worker.url && workers[index].tab.index === worker.tab.index) {
        detachWorker(workers[index], workers);
    }
}

虽然我认为这不是正确的方法,但这解决了这个问题(目前)。解决方案的任何进展:)。

4

3 回答 3

6

也碰到了这个。Worker 对象似乎停留在过去的某些页面中(并且在历史上的 Back 和 Forward 时被重用)。解决方案是监听pagehidepageshow事件,以便仅将当前显示的工作人员保留在数组中:

var pageMod = require("sdk/page-mod");
var array = require('sdk/util/array');

var pageWorkers = [];
pageMod.PageMod({
  onAttach: function(worker) {
      array.add(pageWorkers, worker);
      worker.on('pageshow', function() { array.add(pageWorkers, this); });
      worker.on('pagehide', function() { array.remove(pageWorkers, this); });
      worker.on('detach', function() { array.remove(pageWorkers, this); });
      // do other work.
  }
});

请注意,该array.add函数负责不添加重复项。

于 2013-11-27T19:29:20.870 回答
1

不确定我有没有遇到你的问题。您提到的事件detach也会在重新加载选项卡时发出:

const { add, remove } = require("sdk/util/array");
const workers = [];

require("sdk/page-mod").PageMod({
  include: "*",
  contentScript: "alert('executed')",
  onAttach: function(worker) {
    add(workers, worker);
    console.log('attached: ', workers.length);

    worker.on('detach', function() {
      remove(workers, worker);
      console.log('detached: ', workers.length);
    })
  }
});

当我重新加载页面时,将执行分离的侦听器。无论如何,要检查与工作人员关联的选项卡是否是活动选项卡,您应该能够仅比较选项卡对象(workers[index].tab === tabs.activeTab):另请注意,在 Add-on SDK 1.14 中,选项卡也具有该id属性,因此您可以使用它来标识自己。并且for…in不建议使用索引循环:https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...查看描述部分。我宁愿使用for...of

for (let worker of workers) { ... }
于 2013-04-01T17:31:06.473 回答
0

零是正确的,事件detach在重新加载时发出。
但是当我在同一个选项卡中打开不同的页面时,不会发出分离事件!
因此,即,当我在选项卡 1 中加载了某个页面 A 并单击在同一选项卡 1 中打开不同页面 B 的链接时,我必须手动分离页面 A 的工作人员(?)

var workers = [];    

require('page-mod').PageMod({
  include: '*',
  contentScriptWhen: 'end',
  contentScript: [require('self').data.url('bla.js')],
  onAttach: function(worker) {
    var w = workers.length;
    while (w--) {
      if (worker.tab === workers[w].tab) {
        workers.splice(w, 1);
        break;
      }
    }
    workers.push(worker);
    // other stuff
  }
});
于 2013-06-02T09:58:13.117 回答