扩展程序是基于事件的程序,用于修改或增强 Chrome 浏览体验。事件是浏览器触发器,例如导航到新网页、移除书签或关闭标签页。扩展程序会在后台脚本中监控这些事件,然后根据指定指令做出响应。
后台网页在需要时加载,在闲置时卸载。以下是一些事件示例:
- 该扩展程序首次安装或更新到新版本时。
- 后台网页正在监听事件,并且分派了该事件。
- 内容脚本或其他扩展程序用于发送消息。
- 扩展程序中的另一个视图(例如弹出式窗口)会调用
runtime.getBackgroundPage
。
加载完成后,只要后台网页正在执行操作(例如调用 Chrome API 或发出网络请求),它就会保持运行状态。此外,除非关闭所有可见视图和所有消息端口,否则后台页面不会卸载。请注意,打开视图不会导致事件页面加载,而只会阻止该页面在加载完成后关闭。
有效的后台脚本会保持休眠状态,直到它们监听火灾事件,使用指定指令作出响应,然后卸载。
注册后台脚本
后台脚本在清单的 "background"
字段下注册。它们会列在 "scripts"
键后面的数组中,且 "persistent"
应指定为 false。
{
"name": "Awesome Test Extension",
...
"background": {
"scripts": ["background.js"],
"persistent": false
},
...
}
您可以为模块化代码注册多个后台脚本。
{
"name": "Awesome Test Extension",
...
"background": {
"scripts": [
"backgroundContextMenus.js",
"backgroundOmniBox.js",
"backgroundOauth.js"
],
"persistent": false
},
...
}
如果扩展程序当前使用的是持久性后台页面,请参阅后台迁移指南,了解如何切换到非持久性模型。
初始化该扩展程序
监听 runtime.onInstalled
事件,以在安装扩展程序时初始化扩展程序。使用此事件来设置状态或一次性初始化,例如上下文菜单。
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"]
});
});
设置监听器
围绕扩展程序所依赖的事件设计后台脚本的结构。定义功能相关的事件可以让后台脚本休眠,直到这些事件被触发,并防止扩展程序错过重要的触发器。
监听器必须从网页开头开始同步注册。
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"]
});
});
// This will run when a bookmark is created.
chrome.bookmarks.onCreated.addListener(function() {
// do something
});
请勿异步注册监听器,因为系统不会正确触发监听器。
chrome.runtime.onInstalled.addListener(function() {
// ERROR! Events must be registered synchronously from the start of
// the page.
chrome.bookmarks.onCreated.addListener(function() {
// do something
});
});
扩展程序可以通过调用 removeListener
从后台脚本中移除监听器。如果移除了某个事件的所有监听器,Chrome 将不再针对该事件加载扩展程序的后台脚本。
chrome.runtime.onMessage.addListener(function(message, sender, reply) {
chrome.runtime.onMessage.removeListener(event);
});
过滤事件
使用支持事件过滤器的 API 将监听器限制为扩展程序关注的情况。如果扩展程序正在监听 tabs.onUpdated
事件,请尝试改用带有过滤条件的 webNavigation.onCompleted
事件,因为 Tab 键 API 不支持过滤条件。
chrome.webNavigation.onCompleted.addListener(function() {
alert("This is my favorite website!");
}, {url: [{urlMatches : 'https://www.google.com/'}]});
响应监听器
监听器的作用是在事件触发时触发功能。如需对事件做出响应,请在监听器事件中构建所需的回应结构。
chrome.runtime.onMessage.addListener(function(message, callback) {
if (message.data == "setAlarm") {
chrome.alarms.create({delayInMinutes: 5})
} else if (message.data == "runLogic") {
chrome.tabs.executeScript({file: 'logic.js'});
} else if (message.data == "changeColor") {
chrome.tabs.executeScript(
{code: 'document.body.style.backgroundColor="orange"'});
};
});
卸载后台脚本
您应定期保留数据,以便在未收到 onSuspend
的情况下扩展程序崩溃时不会丢失重要信息。可以使用 storage API 来协助完成。
chrome.storage.local.set({variable: variableInformation});
如果扩展程序使用消息传递方式,请确保所有端口都已关闭。在所有消息端口关闭之前,后台脚本不会卸载。通过监听 runtime.Port.onDisconnect 事件,可深入了解打开的端口何时关闭。使用 runtime.Port.disconnect 手动关闭它们。
chrome.runtime.onMessage.addListener(function(message, callback) {
if (message == 'hello') {
sendResponse({greeting: 'welcome!'})
} else if (message == 'goodbye') {
chrome.runtime.Port.disconnect();
}
});
通过监控扩展程序条目在 Chrome 的任务管理器中何时出现和消失,可以观察后台脚本的生命周期。
点击 Chrome 菜单,将光标悬停在更多工具上,然后选择“任务管理器”,即可打开任务管理器。
后台脚本会在几秒钟不活动后自行卸载。如果需要在最后时刻进行清理,请监听 runtime.onSuspend
事件。
chrome.runtime.onSuspend.addListener(function() {
console.log("Unloading.");
chrome.browserAction.setBadgeText({text: ""});
});
不过,应优先考虑持久保留数据,而不是依赖于 runtime.onSuspend
。这样做无法实现尽可能多的清理,即使发生崩溃也不会有任何帮助。