通过 Google Chrome 扩展将代码注入 Gmail - 如何确保我的脚本在完成加载后被注入?

Code injection into Gmail via a Google Chrome extension - how to make sure that my script gets injected when it has finished loading?

我正在创建一个 Google Chrome 扩展,它通过注入我编写的脚本向 Gmail 添加一些额外的功能。 'injected script'请看this definition.

为此,我的内容脚本匹配 ["https://mail.google.com/mail/*"]

但是,问题在于这与 Gmail 正在加载和完成加载时的情况相同 URL。因此,我的脚本有时似乎过早注入,而 Gmail 仍在加载,导致引用错误。

为了避免这个问题,我只是 运行 通过执行以下操作来加载我的脚本: window.addEventListener("load", runInjectedScript);

并且在我的内容脚本(执行注入)中,它仅在条件为真时注入:if (window.self === window.top).

然而,这些措施似乎并不能保证我的脚本总是会在正确的时间注入,一旦 Gmail 完成加载并出现收件箱。 我怎样才能确保发生这种情况?有没有我没有实现的技术?

您可能 运行 setInterval 检查您在 Gmail 中拦截的数据是否可用。

var gmailLoaded = setInterval(function () {
    if (typeof GMAIL !== 'undefined') {
        runInjectedScript();
        clearInterval(gmailLoaded);
    }
}, 100);

您需要将 GMAIL 替换为您尝试从 Gmail 引用的任何内容。您也可以使用上面相同的方法检查加载状态是否处于活动状态,但这可能会增加额外的开销。

要确保在 "inbox appears" 时注入脚本,请查看 MutationObserver, which provides a way to react to changes in the DOM, in particular for observing the input being inserted

我检查了 gmail 页面,收件箱加载后,他们将 style="display: none" 添加到 #loading 元素。

您可以进行一些轮询以更改它,然后 bootstrap 您的应用程序。

function onInboxLoaded(cb) {
  var pollInterval = setInterval(function() {
    var elem = document.getElementById('loading');
    if (elem && elem.style.display === 'none') {
      clearInterval(pollInterval);

      cb();
    }
  }, 100);
}

onInboxLoaded(function(){
  // bootstrap app
})