Chrome扩展程序代码与内容脚本与注入脚本

Jon*_*Jon 57 javascript scope google-chrome-extension content-script

我试图让我的Chrome扩展程序在init()加载新页面时运行该功能,但我无法理解如何执行此操作.根据我的理解,我需要在background.html中执行以下操作:

  1. 使用chrome.tabs.onUpdated.addListener()来检查时,页面变更
  2. 使用chrome.tabs.executeScript运行的脚本.

这是我的代码:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    chrome.tabs.executeScript(null, {code:"init();"});
});

//script.js
function init() {
    alert("It works!");
}
Run Code Online (Sandbox Code Playgroud)

我也想知道init()函数是否可以访问其他JS文件中的其他函数?

Rob*_*b W 161

Chrome扩展程序中的JavaScript代码可分为以下几组:

  • 扩展代码 - 对所有允许的chrome.*API的完全访问权限.
    这包括后台页面,并且必须通过直接访问的所有页面chrome.extension.getBackgroundPage(),如浏览器弹出窗口.

  • 内容脚本(通过清单文件或chrome.tabs.executeScript) - 部分访问某些chromeAPI,完全访问页面的DOM(包括任何window对象,包括框架).
    内容脚本在扩展和页面之间的范围内运行.window内容脚本的全局对象与页面/扩展的全局命名空间不同.

  • 注入脚本(通过内容脚本中的此方法) - 对页面中所有属性的完全访问权限.无权访问任何chrome.*API.
    注入的脚本的行为就像页面本身包含它们一样,并且没有以任何方式连接到扩展.请参阅此文章以了解有关各种注射方法的更多信息.

要将注入的脚本中的消息发送到内容脚本,必须使用事件.请参阅此答案以获取示例.注意:在一个扩展中从一个上下文传输到另一个上下文的消息会自动(JSON)进行序列化和解析.


在您的情况下,chrome.tabs.onUpdated可能在script.js评估内容脚本之前调用后台页面()中的代码.所以,你会得到一个ReferenceError,因为init不是.

此外,在使用时chrome.tabs.onUpdated,请确保测试页面是否已完全加载,因为事件会触发两次:加载前和完成时:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete') {
        // Execute some script when the page is fully (DOM) ready
        chrome.tabs.executeScript(null, {code:"init();"});
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 感谢您提供有关“chrome.tabs.onUpdated”触发两次的提示。所以我想我的问题是如何注入`init()`?我应该注入所有 JavaScript 吗?当用户单击浏览器操作图标时,通常会调用“init()”,并且“init()”会触发许多其他函数。 (2认同)
  • @pvnarula如果它占用大量CPU,请考虑在后台页面中使用Worker。如果有昂贵的一次性初始化步骤,请使用后台脚本。另一方面,如果某些标签/页面特定的代码例如高度依赖DOM(并且后台页面的响应能力很重要),请使用内容脚本,因为在一个标签中执行JavaScript不会干扰另一个标签,而将其放在后台页面会阻止扩展程序的后台脚本响应其他事件。 (2认同)