监听器多次实例化

时间:2013-07-25 09:41:21

标签: google-chrome-extension listener

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

background.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)

,即使我再次从弹出窗口运行程序,所有监听器都将被删除,程序也不再起作用。

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

我想我必须从内容脚本启动听众,这不会解决问题,但我不知道如何从我的听众那里制作单身。

1 个答案:

答案 0 :(得分:0)

每次显示弹出窗口时,都会运行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。)
请查看 docuemntation 以获取更多信息和说明。