javascript - 发送消息到后台页面,更新html,然后在选项卡中显示

标签 javascript html google-chrome-extension

我有一个 chrome 扩展,用户输入一些信息并生成报告。当然,现在该报告每次都会根据用户输入的内容而有所不同。

我想要实现的目标是让我的扩展说:

Hey, Mr. Background page. Here's the information you need, now build some html based off what I've given you and show it to the user.

这是我正在使用的 manifest.json:

{
  "manifest_version": 2,

  "name": "XXXX",
  "description": "XXXX",
  "version": "1.0.0",
  "permissions": ["storage", "tabs"],
  "options_page": "settings.html",

  "background":
  {
    "page": "background.html"
  },

  "content_scripts":
  [
    {
      "matches": ["<all_urls>"],
      "js": ["js/jquery-3.1.1.min.js", "js/bootstrap.min.js", "js/main.js", "js/background.js"],
      "css": ["css/bootstrap.min.css", "css/font-awesome.min.css"]
    }
  ],

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "icons": { "128": "logo.png" }
}

这是我的background.html

<html>
<body>
    <script src="js/jquery-3.1.1.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/background.js"></script>
</body>
</html>

这是我的background.js

$(document).ready(function() {
    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        $("body").html(msg.message);
        console.log("Message from: " + msg.message);
    });
});

现在,当用户单击我的扩展程序上的按钮时,我使用以下代码发送消息:

$("#generate").click(function() {
    chrome.tabs.create({url: 'background.html'});
    chrome.runtime.sendMessage({
        message: "Sample message."
    });
});

现在我期望发生的情况是打开我的 background.html 页面,然后根据发送的消息更改页面正文,但这不起作用。

有什么想法吗?

最佳答案

您尝试使用同一页面作为背景并显示某些内容,从而犯了巨大的概念错误。这可能会导致非常不可预测的行为。

您实际上是在尝试使用 background.html 打开一个选项卡,并以某种方式期望它是“相同的”背景页面。它不是这样工作的 - 您正在打开同一文档的新实例。想象一下在两个选项卡中打开同一个 Web 表单 - 您不希望它们反射(reflect)输入到字段中的文本。

最重要的是,弹出页面与打开选项卡的交互存在很多错误。

所以,行动计划:

  1. 如果您确实需要在(永久不可见)后台页面中执行一段代码,请按惯用方式将其称为 background.js 并切换到 scripts -样式背景页面定义:

    "background": {
      "scripts": ["background.js"]
    }
    

    此外,请考虑使用Event pages .

  2. 为了您的理智,无论您使用什么来显示报告,都不应该将其称为背景。将其重命名为 report.html/report.js

  3. 在您的弹出代码中,您的错误#1 是时机。您打开一个应该监听您的消息的页面,但不要等待它准备好监听。如果您想确保页面实际打开并准备就绪,您应该使用 tabs.create 的回调。

    chrome.tabs.create({url: "report.html"}, function(tab) {
      // Okay, now it's ready, right? Right?..
      chrome.runtime.sendMessage(/*...*/);
    });
    
  4. 但是,这样做不会解决问题,因为默认情况下打开新选项卡会将其聚焦(这大概是您想要的),这会立即强制弹出窗口关闭。一旦选项卡获得焦点,您就无法阻止它。但这意味着您的消息不会被发送:弹出窗口将在其发生之前被销毁。

    所以,不要依赖消息传递。想必,您可以store您的报告基于存储中的任何数据。因此,首先设置它,然后打开报告页面,您可以在其中读取数据并构建报告。

    // Popup
    chrome.storage.local.set({foo: bar}, function() {
      // Storage is updated, it's showtime!
      chrome.tabs.create({url: "report.html"});
      // And now, we die, inevitably. Goodbye, cruel world.
    });
    
    // Report
    chrome.storage.local.get("foo", function(data) {
      // Oh, what joy is to have data.foo in here!
    });
    

关于javascript - 发送消息到后台页面,更新html,然后在选项卡中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40173752/

相关文章:

javascript - 根据div的内部文本计算高度

javascript - 检测动态加载的 iframe

javascript - Jquery 找到一个类型的第一个直接 child

javascript - 如何使用 jquery 将多个按钮 id 复制到剪贴板

javascript - 使用 Javascript 更改 HTML 元素的类

javascript - 捆绑的 Webextension 看不到 JQuery

javascript - 在 Chrome 扩展内容脚本中执行代码时,在光标处的文本区域/文本输入中插入文本

javascript - 在div中水平和垂直对齐图像

javascript - 为什么 jQuery 找不到这个 react.js 元素?

javascript - 访问 <div> 中的 <span> 文本