4

我正在开发一个 Chrome 扩展程序,其中有一个调用 background.js 的“开始”功能的弹出窗口。Background.js 打开标签,我在 background.js 中有一个监听器,它向标签的 content_script.js 发送消息:

背景.js

function begin() {
  var mySendedTabs = new Array();
  chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
  {             
   if(mySendedTabs.indexOf(tabId) == -1) {
    if(changeInfo.status == "complete")
    {
     chrome.tabs.sendMessage(tabId, { question: "What's your location ?" });
     mySendedTabs.push(tabId);                      
    }
   }                
 });
}

content_script.js 回复另一条消息:

chrome.runtime.onMessage.addListener(
 function(request, sender, sendResponse) {
  if(request.question == "What's your location ?") {
   alert("Got a location request");
   chrome.runtime.sendMessage({myLocation : location.href});
  }
});

当我从“chrome://extensions/”窗口刷新我的扩展时没有问题。问题是,如果我第二次(从弹出窗口)运行我的程序,content_script.js 中的警报会被触发 2 次。如果我再次运行我的程序,警报会被触发 3 次......等等。

在我看来,尽管在我从弹出窗口启动程序时刷新了 background.js,但侦听器仍在内存中,并且侦听器被复制了。

如果我打电话

chrome.tabs.onUpdated.removeListener(arguments.callee)

,所有侦听器都被删除并且程序不再工作,即使我从弹出窗口再次运行程序。

当我从弹出窗口启动程序时,我只想获得一个干净的浏览器窗口。

我想我必须从内容脚本启动侦听器,这不能解决问题,但我不知道如何从我的侦听器中制作单例。

4

1 回答 1

1

每次显示弹出窗口时,您的 begin 方法都会运行,这又会添加另一个侦听器,因此您最终会遇到越来越多的侦听器是正常的。您需要做的是将添加侦听器的代码移到begin()方法之外。应在加载背景页面时添加一次侦听器。然后你也应该把它放在方法mySendedTabs之外begin()(这样监听器就可以访问它了)。

我不确定我是否理解您所说的“当我从弹出窗口启动程序时,我只想获得一个干净的浏览器窗口。”,但是(如果我的猜测是正确的)您在该begin()方法中需要做的就是重新初始化mySendedTabs变量。

您的 background.js 可能如下所示:

var mySendedTabs = new Array();
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {             
    if (mySendedTabs.indexOf(tabId) == -1) {
        if(changeInfo.status == "complete") {
            chrome.tabs.sendMessage(tabId, { question: "What's your location ?" });
            mySendedTabs.push(tabId);
        }
    }
});

function begin() {
    mySendedTabs = new Array();
}

(我假设变量mySendedTabs在创建选项卡时填充了 tabID(通过回调)。)

更新
顺便说一句,将背景页面变成活动页面是个好主意。(在您的情况下,它只需要添加persistent: false您的清单。)
查看文档以获取更多信息和说明。

于 2013-08-09T08:57:39.500 回答