问题背景
最近我在开发Chrome浏览器插件时,遇到了一个需要脚本初始化的问题。在插件被安装后或浏览器标签页被刷新时,我需要重新初始化插件。为了实现这一点,我研究了Chrome提供的几个API接口,它们分别是chrome.runtime.onInstalled.addListener
、chrome.runtime.onStartup.addListener
以及chrome.tabs.onUpdated.addListener
。在本文中,我将对这三个关键事件监听器进行梳理,并详细说明它们之间的区别。
事件监听器
使用注意项
事件监听器通常是在 background.js
文件中使用,因为 background.js
是扩展程序的后台脚本,负责管理扩展的生命周期和处理事件。不过,也可以在其他 JavaScript 文件中使用事件监听器,只是使用一些特殊的方法:
1、可以在扩展程序的 manifest.json
中声明多个后台脚本。
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0",
"background": {
"service_worker": ["background1.js", "background2.js"]
},
"permissions": [
"tabs",
"storage",
"activeTab",
"scripting"
]
}
2、通过模块化的方式,将事件监听器相关的代码组织到不同的模块中,然后在 background.js
中导入和使用这些模块。
// eventHandlers.js
export function setupEventListeners() {
chrome.runtime.onInstalled.addListener(() => {
console.log('Extension installed');
});
chrome.runtime.onStartup.addListener(() => {
console.log('Browser startup');
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && tab.url.includes('https://juejin.cn/')) {
console.log('Page loaded: ', tab.url);
}
});
}
// background.js
import { setupEventListeners } from './eventHandlers.js';
setupEventListeners();
3、虽然内容脚本或其他页面脚本,无法直接监听扩展的生命周期事件,但是如果需要与后台脚本通信,可以使用消息传递的方式。
// contentScript.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'pageLoaded') {
console.log('Content script received page loaded message');
// 执行相关操作
}
});
// background.js
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && tab.url.includes('https://juejin.cn/')) {
chrome.tabs.sendMessage(tabId, { action: 'pageLoaded' });
}
});
chrome.runtime.onInstalled.addListener 的应用场景
触发时机:
- 当扩展程序被首次安装时触发。
- 当扩展程序被更新到新版本时触发。
- 当 Chrome 浏览器被更新到新版本时触发(扩展程序的清单文件中指定了
manifest_version
为2,而不是3)。
适用场景:
- 一次性初始化任务:适用于在扩展程序安装或更新时执行一次性的初始化任务,例如设置初始配置、显示欢迎页面、注册持久性任务等。
- 注册内容脚本:在扩展程序安装或更新时,可以通过该事件注册内容脚本,以便在特定网站上执行 JavaScript 代码。这对于在特定页面上执行定制化操作非常有用。
- 创建上下文菜单:可以在安装或更新扩展程序时创建右键菜单项,以提供更方便的用户体验。例如,可以添加 “在新标签页中打开链接” 的选项。
- 初始化存储:设置或重置存储中的初始数据。这对于在扩展程序启动时需要一些默认设置或数据非常有用。
代码示例
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
console.log('扩展程序已安装');
// 执行安装时的初始化任务
// 例如:设置默认配置
chrome.storage.sync.set({color: 'blue'}, function() {
console.log('默认颜色设置为蓝色');
});
} else if (details.reason === 'update') {
console.log('扩展程序已更新');
// 执行更新时的任务
// 例如:迁移存储中的旧数据
}
});
chrome.runtime.onStartup.addListener 的应用场景
触发时机:
- 当 Chrome 浏览器启动时触发(包括重新启动)。
- 当用户首次启动浏览器并登录他们的 Google 账号,或者当用户在已经启动的浏览器中切换到不同的 Chrome 账号时
用途:
-
重复初始化任务:适用于在每次浏览器启动时执行初始化任务,例如恢复扩展程序的状态、重新注册临时任务等,或者在启动时清理上一次运行中留下的数据。
-
检查并恢复状态:在浏览器启动时检查并恢复扩展程序的状态。从存储中读取上次保存的状态,并恢复这些状态。例如,恢复用户设置的选项,恢复上次浏览的页面等。
-
重新注册动态内容脚本:重新注册在运行时添加的内容脚本。这样可以确保内容脚本在目标页面上始终有效。
-
初始化连接:建立必要的连接或重新初始化服务。例如,与后台服务器重新建立连接,初始化 WebSocket 等。
代码示例
chrome.runtime.onStartup.addListener(() => {
console.log('Chrome 浏览器已启动或用户已登录');
// 恢复扩展程序的状态
chrome.storage.sync.get(['color'], function(result) {
if (result.color) {
console.log('启动时获取的颜色是:' + result.color);
} else {
console.log('没有设置颜色,使用默认值');
chrome.storage.sync.set({color: 'blue'}, function() {
console.log('默认颜色设置为蓝色');
});
}
});
// 重新注册动态内容脚本
chrome.scripting.registerContentScripts([{
id: 'myContentScript',
matches: ['https://juejin.cn/*'],
js: ['contentScript.js'],
runAt: 'document_end'
}]);
// 初始化连接,例如 WebSocket
const socket = new WebSocket('wss://xiaodou.com/socket');
socket.onopen = () => {
console.log('WebSocket 连接已建立');
};
socket.onmessage = (event) => {
console.log('收到消息:', event.data);
};
socket.onclose = () => {
console.log('WebSocket 连接已关闭');
};
});
chrome.tabs.onUpdated.addListener 的应用场景
触发时机
当标签页的状态更新时触发,这包括页面加载开始、页面加载完成、URL 更改等情况。
用途
-
监听页面更新:通过监听标签页的更新事件,可以在页面加载开始、加载完成或 URL 发生变化时执行特定操作。例如,可以记录用户访问的页面,或者在页面加载完成时执行一些数据采集或分析任务。
-
在特定页面上动态注入脚本或样式:可以根据 URL 动态决定是否注入特定的内容脚本或样式表。例如,当用户访问某个网站时,自动注入脚本来修改页面的外观或功能,提升用户体验。
-
根据页面加载状态更新扩展图标、弹出页面等:根据页面的加载状态,动态改变扩展程序的图标,或者更新弹出页面的内容。例如,当用户访问某个特定网站时,扩展程序的图标变为特定颜色,或者弹出页面显示该网站的特定信息。
代码示例
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
// 仅在页面加载完成时触发
if (changeInfo.status === 'complete' && tab.url) {
// 例如:检查是否为特定网站
if (tab.url.includes('https://juejin.cn/')) {
console.log('页面加载完成: ', tab.url);
// 动态注入脚本
chrome.scripting.executeScript({
target: { tabId: tabId },
function: () => {
// 示例:向页面注入脚本
console.log('在页面上执行脚本');
// 在页面右下角添加一个导出按钮
const button = document.createElement('button');
button.textContent = '导出';
button.style.position = 'fixed';
button.style.bottom = '10px';
button.style.right = '10px';
button.style.zIndex = 1000;
document.body.appendChild(button);
}
});
}
}
});
最后象征性的总结一下,就是基本的使用场景如下所示
chrome.runtime.onInstalled.addListener(() => {
// 执行安装或更新时的一次性初始化任务
});
chrome.runtime.onStartup.addListener(() => {
// 执行每次启动时需要重复进行的任务
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
// 在特定页面更新完成后执行任务
}
});
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Chrome扩展程序开发新手指南:事件监听器的应用技巧
发表评论 取消回复