Chrome 扩展 js:在后台.js和弹出窗口.js之间共享功能

Chrome Extension js: Sharing functions between background.js and popup.js

本文关键字:js 窗口 之间 共享 功能 扩展 后台 Chrome      更新时间:2023-09-26

假设我有一个JavaScript函数foo()我想在后台和popup.html中执行。

例如:它每小时在我的Chrome扩展程序的后台执行一次,但也可以由用户通过单击按钮从弹出菜单(popup.html)激活。

我目前有一个定义foo()global.js脚本,当我在popup.js文档中包含对foo()的调用时,它们执行起来没有问题。(如果我在popup.html中包含两个脚本)

但是,当我尝试访问background.js内部的foo()时,调用不会执行(即使global.js包含在"后台"manifest.json"扩展文件中:

"background": {
    "persistent": true,
    "scripts": ["background.js", "global.js"]
},

有没有一种方便的方法可以在background.jspopup.js之间共享函数(而无需将整个函数复制到每个函数中)?

后台脚本按清单文件中指定的顺序加载。只需在后台脚本之前使用通用代码加载文件,如下所示:

"background": {
    "persistent": true,
    "scripts": ["global.js", "background.js"]
},

除了复制弹出窗口中的代码,您还可以使用弹出窗口中的chrome.extension.getBackgroundPage()来访问背景页面的功能/变量,例如 chrome.extension.getBackgroundPage().myFunction(); .

您还可以从其他脚本调用函数,就像直接导入所有函数一样。可以使用构造函数和自定义原型来执行此操作。

首先将后台脚本按访问顺序添加到主节日中,并在我们的弹出窗口中作为脚本链接.html在结束正文标签之前:

manifest.json

...
"background": {
"persistent": false,
"scripts": [
  "foo.js",
  "bg.js"
]},
...

在文件 foo 中.js我们创建对象原型。我正在使用模块模式,因为我们希望它是私有的,否则:

傅.js

(() => {
  console.log('foo loaded');       // check that the script has loaded
  window.test = window.test || {}; // check for or create the object
  test.FooFunc = function() {      // setup a constructor to hold defaults
    this.foo = 'bar',
    this.time = '15000'
  }
  test.FooFunc.prototype = {       // add our prototype with a single method
    callConsole: (text) => {
      console.log('FooFunc method loaded from ' + text);
    }
  }
})();

从 bg.js 文件中,我们可以通过实例化一个新的测试对象来不断调用此函数。

BG.js

(() => {
  console.log('bg loaded');            // check that the script has loaded
  var testProto = new test.FooFunc;    // instantiate new test object
  testProto.callConsole('Background!');
})();

加载文件后,一旦单击图标,弹出窗口就会打开,脚本就会触发,包括我们的函数。您应该在控制台中看到类似以下内容:

foo loaded
bg loaded
FooFunc method loaded from Background!

使用多个后台脚本

当然,我们可以继续将更多脚本添加到组合中,只需将它们添加到后台脚本列表中.html并在 bg.js 之前弹出*按照您希望访问它们的顺序**。添加后,从同一庄园中的新脚本为测试对象制作新的原型,然后向每个(测试。Prefs 是一个很好的制作)。

*脚本是按调用顺序加载的,因此如果在想要访问它的脚本之前未创建原型,则它将无法找到新的原型。任何脚本都可以访问原型,只要它们是在调用这些脚本之前创建的。

有关用例场景中的一个很好的例子,您可以查看Chrome的Buildbot Monitor。它不仅展示了私下使用多个脚本的出色过程,还展示了如何使用单个对象来保存多个设置、原型和方法,以便扩展访问。

除了将脚本添加为manifest.json background部分的一部分外,您还必须通过chrome.runtime.getBackgroundPage(callback) API(当前preferred to chrome.extension.getBackgroundPage())访问这些脚本中的内容。

例如,在popup.js或扩展中的其他位置:

chrome.runtime.getBackgroundPage(function(backgroundPageWindow) {
  // Do stuff here that requires access to the background page.
  // E.g. to access the function 'myFunction()'
  console.log("Calling myFunction() " + backgroundPageWindow.myFunction());
});

有关更多详细信息,请参阅 getBackgroundPage 文档和事件页面文档(其中解释了chrome.extension.getBackgroundPage()已弃用)。