如何在 onStartup 和 onInstalled 中添加 Chrome 扩展监听器?

How can I add a Chrome extension listener both onStartup and onInstalled?

chrome.runtime API 有几个事件,我可以使用这些事件将侦听器添加到上下文菜单。目前我正在使用 chrome.runtime.onStartup 像这样:

chrome.runtime.onStartup.addListener(function() {
  chrome.contextMenus.create({
    'title': 'Add: %s',
    'contexts': ['selection']
  });
});

chrome.contextMenus.onClicked.addListener(onClickHandler);

问题是 chrome.runtime.onStartup 将在用户启动或重新启动 Chrome 时工作,而 chrome.runtime.onInstalled 将在首次安装或更新扩展或 Chrome 时工作.

如果我只执行 onStartup,那么当我的扩展程序或 Chrome 下次更新时,我的上下文菜单将不会出现。如果我只执行 onInstalled,那么在用户重新启动 Chrome.

后,我的上下文菜单将不会保留

如何处理这两种情况?

这实际上是一个有趣的问题,因为行为会根据您是否使用 event page or a persistent background page.

而有所不同

请注意,此答案特定于 contextMenu API!

永久后台页面

您应该简单地将您的代码放在顶层。

然后它会在每次加载您的扩展程序的后台页面时执行。

如果你有一个持久的后台页面,那正是你想要的:当扩展启动时执行一次无论什么原因

如果您想确保不创建重复项,请在 create() 中包含一个 id 属性。

Google 有一个 corresponding sample.

活动页面

在扩展程序的整个生命周期中,事件页面的加载频率比常规页面高得多。无论如何,上下文菜单 API 需要 对事件页面进行特殊处理

首先,在 contextMenus.create() 中包含 id 属性是活动页面的 要求 。另外,因为空闲时卸载代码,所以必须使用 chrome.contextMenus.onClicked 而不是 onclick 属性。

文档建议使用 onInstalled:

If you need to do some initialization when your extension is installed or upgraded, listen to the runtime.onInstalled event. This is a good place to register for declarativeWebRequest rules, contextMenu entries, and other such one-time initialization.

确实,这就是他们在 the sample 中所做的。

我对其进行了测试,确实上下文菜单在扩展程序和浏览器重启后仍然存在。不过,没有明确记录这种差异。

错误警报!鉴于Rob W关于this bug的评论,如果扩展恰好被禁用,该方法不是100%可靠的。