我目前正在尝试创建一个Chrome扩展程序,该扩展程序在其弹出窗口中列出所有打开的标签页。稍后将添加更多功能,例如通过弹出窗口关闭特定标签,使用特定URL打开新标签等。
manifest.json
{
"manifest_version": 2,
"name": "List your tabs!",
"version": "1.0.0",
"description": "This extension only lists all of your tabs, for now.",
"background": {
"persistent": true,
"scripts": [
"js/background.js"
]
},
"permissions": [
"contextMenus",
"activeTab",
"tabs"
],
"browser_action": {
"default_popup": "popup.html"
}
}
background.js
const tabStorage = {};
(function() {
getTabs();
chrome.tabs.onRemoved.addListener((tab) => {
getTabs();
});
chrome.tabs.onUpdated.addListener((tab) => {
getTabs();
});
}());
function getTabs() {
console.clear();
chrome.windows.getAll({populate:true},function(windows){
windows.forEach(function(window){
window.tabs.forEach(function(tab){
//collect all of the urls here, I will just log them instead
tabStorage.tabUrl = tab.url;
console.log(tabStorage.tabUrl);
});
});
});
chrome.runtime.sendMessage({
msg: "current_tabs",
data: {
subject: "Tabs",
content: tabStorage
}
});
}
popup.js
(function() {
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.msg === "current_tabs") {
// To do something
console.log(request.data.subject)
console.log(request.data.content)
}
}
);
}());
根据我的理解,由于您应该在background.js
中使用侦听器来更改选项卡。然后,当发生这种情况时,您可以向popup.js
如您所见,目前,我只是在将其附加到div或popup.html
中的某个内容之前,尝试在控制台中登录我的标签以确保其正常工作。但是,这不起作用,因为在我的popup.html
控制台中出现以下错误:
popup.js:3 Uncaught TypeError: Cannot read property 'sendMessage' of undefined
所以我...由于某种限制,我无法在popup.js中使用onMessage,但我也对如何实现我想做的事情一无所知。
任何帮助将不胜感激。
答案 0 :(得分:1)
Google关于后台脚本的文档有点含糊。对于您的用例而言,重要的是,弹出窗口仅在显示时才运行,而在隐藏时不运行,因此您根本不需要background.js,只需将所有内容都放入popup.js中即可在您每次运行时运行显示弹出窗口,这是您的popup.html:
<script src="popup.js"></script>
该错误消息表示您正在直接从磁盘上以file://
页的形式打开html文件,但应通过单击扩展名图标或通过其自己的URL chrome-extension:// id来打开它/popup.html,其中id是您的扩展程序ID。当您点击扩展程序图标时,此操作会自动发生-弹出窗口是具有该URL的单独页面,具有自己的DOM,document
,window
等。
该弹出窗口有其自己的devtool,请参见this answer,其中显示了如何调用它(在Chrome中,通过右键单击弹出窗口内部,然后单击“检查”)。
扩展API是异步的,因此回调将在外部代码完成后在以后的某个点运行,这就是为什么您不能像目前那样在回调之外使用tabStorage
的原因。更多信息:Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference。
应该不必枚举onRemoved和onUpdated中的所有选项卡,因为当打开一百个选项卡时,它可能真的很慢。相反,您可以使用提供给这些事件的侦听器的参数来修改tabStorage,有关详细信息,请参见documentation。这需要tabStorage保留每个标签的ID,因此仅保留来自API的整个响应是有意义的。这是一个简化的示例:
let allTabs = [];
chrome.tabs.query({}, tabs => {
allTabs = tabs;
displayTabs();
});
function displayTabs() {
document.body.appendChild(document.createElement('ul'))
.append(...allTabs.map(createTabElement));
}
function createTabElement(tab) {
const el = document.createElement('li');
el.textContent = tab.id + ': ' + tab.url;
return el;
}