我正在开发一个 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)
,即使我从弹出窗口再次运行程序,所有监听器都被删除并且程序不再运行。
当我从弹出窗口启动程序时,我只想获得一个干净的浏览器窗口。
我想我必须从内容脚本启动监听器,这不会解决问题,但我不知道如何从我的监听器制作单例。
最佳答案
每次显示弹出窗口时,您的 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(通过回调)。)更新 :
顺便说一句,将您的背景页面变成事件页面是个好主意。 (在您的情况下,它只能需要在您的 list 中添加
persistent: false
。)查看 docuemntation 了解更多信息和说明。
关于google-chrome-extension - 监听器实例化多次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17854373/