javascript - 将数据(选项卡)从background.js传递到popup.js

标签 javascript google-chrome google-chrome-extension

我目前正在尝试制作一个 Chrome 扩展,在弹出窗口中列出所有打开的选项卡。稍后将添加更多功能,例如通过弹出窗口关闭特定选项卡、使用特定 URL 打开新选项卡等。

ma​​nifest.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"
  }
}

背景.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 未捕获类型错误:无法读取未定义的属性“sendMessage”

所以我...有点理解,由于某些限制,我无法在 popup.js 中使用 onMessage,但我也不知道如何实现我想要做的事情。

如有任何帮助,我们将不胜感激。

最佳答案

  1. Google 关于后台脚本的文档有点含糊。对于您的用例来说,重要的是弹出窗口仅在显示时运行,隐藏时不会运行,因此您根本不需要 background.js,只需将所有内容放入 popup.js 中,每次您运行时都会运行显示弹出窗口,这是您的 popup.html:

    <script src="popup.js"></script>
    
  2. 错误消息意味着您直接从磁盘将 html 文件作为 file:// 页面打开,但应通过单击扩展程序图标或通过其自己的 URL chrome 打开它-extension://id/popup.html 其中 id 是您的扩展程序的 id。当您单击扩展程序图标时,这种情况会自动发生 - 弹出窗口是具有该 URL 的单独页面,具有自己的 DOM、文档窗口 等。

  3. 弹出窗口有自己的开发工具,请参阅 this answer显示如何调用它(在 Chrome 中,通过在弹出窗口内右键单击,然后单击“检查”)。

  4. 扩展 API 是异步的,因此回调会在外部代码完成后稍后运行,这就是为什么您不能在回调之外使用 tabStorage,例如你现在做的。更多信息:Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference .

  5. 应该没有必要在 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;
    }
    

关于javascript - 将数据(选项卡)从background.js传递到popup.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57183918/

相关文章:

css - 跨浏览器的背景图像位置存在细微差异

google-chrome-extension - 在从 Google Chrome 网上商店安装我的 google-chrome-extension 之前,如何让用户同意我的 EULA?

javascript - 在 chrome 扩展中加载 Polymer 1.0 时出现问题

JavaScript 不使用其他 JS 文件中的变量

函数返回的Javascript(node.js)值未定义?

javascript - 如何知道在chrome控制台中哪个文件定义了js全局变量?

javascript - chrome 扩展可以将第三方 cookies/存储列入白名单吗?

javascript - 使用 dojo.data.ObjectStore 刷新增强网格

javascript - 外部 javascript 文件中的函数仅在重新加载时调用 在 React js 中

CSS3 改变了浏览器之间的操作方式