【问题标题】:Addon SDK - context-menu and page-mod workers插件 SDK - 上下文菜单和页面模块工作者
【发布时间】:2013-03-19 14:20:51
【问题描述】:

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

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

我现在有两个相同的工人,但就像旧的工人已经过期了。这意味着 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(){}) 应该处理这个问题,但似乎这只是在关闭选项卡时。​​p>

任何建议将不胜感激。

添加 好的,稍事休息后,我决定使用其他地方推荐的 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);
    }
}

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

【问题讨论】:

    标签: javascript firefox-addon-sdk


    【解决方案1】:

    也遇到了这个。 Worker 对象似乎停留在过去的一些页面中(并且在历史上的 Back 和 Forward 时被重用)。解决办法是监听pagehidepageshow事件,只保留当前显示的workers在数组中:

    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 函数负责不添加重复项。

    【讨论】:

      【解决方案2】:

      不确定我是否遇到了您的问题。您提到的事件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...in 检查描述部分。我宁愿使用for…of

      for (let worker of workers) { ... }
      

      【讨论】:

      • 这看起来很有希望,我已经走了这么远的路,现在我不得不回溯一点,但我会试一试。
      • 我认为我的问题很明显,因为:a)我正在使用 pagemod 观看一个页面,并且 b)有一个上下文点击,它也会根据工作人员(在工作人员中)的结果修改相同的 DOM。当我不执行上下文单击但第二次刷新页面时,问题就出现了。 “页面隐藏等等等等”。当我有时间时,我会一起做一个演示来说明。喜欢数组util!
      【解决方案3】:

      零是正确的,事件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
        }
      });
      

      【讨论】:

      • 我还没有找到解决这个问题的方法,工人将在任何给定的刷新时重新生成,从而导致重复。使用chrome.extension.onRequest.removeListener(),Chrome 似乎可以更有效地处理这个问题
      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多