从 Chrome 扩展动态注入 JS 时从 onload() 内部调用方法?

Calling a method from inside onload() when dynamically injecting JS from Chrome extension?

This fantastic answer 展示了如何从 Chrome 扩展名动态地将 JavaScript 插入到页面中:

var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('script.js');
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

调用onload()函数时,它是在浏览器页面的隔离世界中执行的,而不是扩展程序的隔离世界,对吧?

假设这是正确的,我遇到了一个我不明白的问题。

在我的 script.js 中,我有类似这样的代码:

var globalObj = globalObj || {};
globalObj.method = function () {
    console.log('hey!');
};

然后我把上面的onload()函数改成了:

s.onload = function() {
    this.parentNode.removeChild(this);

    globalObj.method();
};

但是控制台显示错误:

Uncaught ReferenceError: globalObj is not defined

为什么 globalObj 没有在 onload() 函数内部定义?

onload 在内容脚本上下文中执行,而不是在页面上下文中执行。

要在页面上下文和脚本上下文之间进行通信,您可以使用多种方法;例如,自定义 DOM 事件将实现您在这里的需要:

// Content script
s.onload = function() {
  this.parentNode.removeChild(this);
  var event = new CustomEvent("invokeMethod");
};

// script.js
window.addEventListener("invokeMethod", function(evt) {
  globalObj.method();
}, false);