Chrome扩展程序开发新手指南:事件监听器的应用技巧

问题背景

最近我在开发Chrome浏览器插件时,遇到了一个需要脚本初始化的问题。在插件被安装后或浏览器标签页被刷新时,我需要重新初始化插件。为了实现这一点,我研究了Chrome提供的几个API接口,它们分别是chrome.runtime.onInstalled.addListenerchrome.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'}]);// 初始化连接,例如 WebSocketconst 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') {// 在特定页面更新完成后执行任务}
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[面试题]Redis

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis 什么是 Redis &#xff…

随机产生一些江河上的坐标数据

不久前收到一个需求,说要随机创建约一百个某段江河上的坐标点,用于做一些数据呈现。 我首先是想到用AI直接给我一点数据,没想到给出来的坐标,有许多都落在陆地上,根本不符合我的要求。后来结合AI给出的建议&#xff0…

生成对抗网络——GAN深度卷积实现(代码+理解)

本篇博客为 上篇博客的 另一个实现版本,训练流程相同,所以只实现代码,感兴趣可以跳转看一下。 生成对抗网络—GAN(代码理解) http://t.csdnimg.cn/HDfLOhttp://t.csdnimg.cn/HDfLO 目录 一、GAN深度卷积实现 1. 模型…

面试题分享--Spring02

Spring 框架中都用到了哪些设计模式?(必会) 1. 工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例 2. 单例模式:Bean 默认为单例模式 3. 代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成…

The First项目报告:深度解读Layer 2生态zkSync

zkSync发币了,这个无数撸毛党心心念念数年之久的项目终于要来了,zkSync 是由Matter Labs 于2019 年推出的以太坊Layer 2 扩容解决方案,作为L2龙头项目之一,与其同属一个层次的L2四大天王之三Optimism、Arbitrum、zkSync、StarkNet…

Profibus协议转Modbus协议网关模块帮助PLC实现智能激光设备通讯

一、前言 Profibus转Modbus网关(XD-MDPB100)是一种工业通信协议转换设备,用于实现Profibus协议与Modbus协议之间的转换。Profibus转Modbus网关在工业自动化系统中具有广泛的应用,它解决了不同协议设备之间的通信问题。本文将深入…

怎么样判断真假单北斗

国产化替代正在中国各行各业逐步提升中,特别涉及重点产业——国家安全! 只有仅支持B1I和B3信号的芯片才是真正的单北斗芯片。但凡你支持了B1C、B2a、B2b中的一个就是假的单北斗。 B1C/L1/E1、B2a/ L5/E5a、B2b/G3/E5b这些频点与其他GNSS系统是完全重合的…

湖北科技学院2024年成人高等继续教育招生简章

湖北科技学院,这所坐落在荆楚大地的高等学府,一直以来都是培养各类专业人才的重要基地。随着社会的快速发展,终身学习的理念深入人心,成人高等继续教育作为满足广大成年人提升学历、增强职业技能的重要途径,受到了越来…

Java输入输出语句 和 保留字

目录 键盘输入语句 保留字 键盘输入语句 Input.java , 需要一个 扫描器(对象), 就是Scanner 步骤 : 导入该类的所在包, java.util.*创建该类对象(声明变量)调用里面的功能 案例要求:可以从控制台接收用户信息,【姓…

润滑不良:滚珠花键磨损的隐形杀手!

滚珠花键作为一种精密机械传动元件,被广泛应用于各种机器和设备中,起着传递动力和运动的重要作用。滚珠花键经过长时间的运行,难免会多少些磨损,严重的话还会导致设备不能正常运转。那么,如何保证它的正常运行呢&#…

88. 合并两个有序数组(简单)

88. 合并两个有序数组 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转:88. 合并两个有序数组 2.详细题解 两个数组均有序(非递减),要求合并两个数组,直观的思路,借助第三个数…

【Linux环境下Hadoop部署】—报错“Unit ntpd.service could not be found.“

项目场景: 执行 “systemctl status ntpd” 命令。 问题描述 报错:Unit ntpd.service could not be found. 原因分析: 没有安装ntp 解决方案: 执行 “yum install ntp” 命令,再次执行 “systemctl status ntpd” 命令…

Docker部署私有仓库Harbor

Harbor构建Docker私有仓库 文章目录 Harbor构建Docker私有仓库资源列表一、部署Docker-Compose服务1.1、下载最新Docker-Compose1.2、查看Docker-Compose版本 二、部署Harbor服务2.1、下载Harbor安装程序2.2、配置Harbor参数文件2.3、所需参数和可选参数2.3.1、所需参数2.3.2、…

平庸的学术工作者

自己进入学术这条路,差不多十年了,回想自己目前的成果,自我评价为平庸。如果将同领域清华的年轻学者打分为 100 分的话,我将自己打分 65。 到目前为止,并不觉得智力因素在管理科学与工程领域的科研中有太大决定作用&a…

Demeditec Diagnostics DmbH兽医诊断类科研试剂

此类产品包括用于多种动物物种包括狗(犬)、猫、牛、马、大鼠和小鼠等分析物的检测。 皮质酮酶联免疫检测试剂盒(Corticosterone rat/mouse Elisa Kit) 产品编号:DEV9922 皮质酮是肾上腺皮质在应答促肾上腺皮质激素时所产生的一种糖皮质激素,是醛甾酮前…

CP AUTOSAR标准之MemoryDriver(AUTOSAR_CP_SWS_MemoryDriver)

1 简介和功能概述 该规范描述了AUTOSAR基础软件模块内存驱动程序(Mem)的功能、API和配置。   内存驱动程序提供访问不同类型内存设备的基本服务,如读取、写入、擦除和空白检查。   尽管闪存仍然是最常见的非易失性存储器技术,但内存驱动程序规范考虑了所有相关的内存设备…

SS928的SVP_NNN和NNN的区别

图像分析引擎 2 (SVP_NNN)与图像分析引擎 1 (NNN)在多个方面存在差异,以下是一些主要的区别和使用上的差异点: 接口风格差异: 图像分析引擎 1 使用 ACL 接口,而图像分析引擎 2 使用 …

虚拟警示教育馆如何革新安全教育?揭秘其深远意义与实际优势

一、推动警示教育的创新与普及 虚拟警示教育馆是将传统警示教育与现代科技相结合的新型教育模式。其意义主要体现在以下几个方面: 1、增强教育的互动性和沉浸感:虚拟警示教育馆通过3D建模、VR等技术,创建逼真的警示场景。这种身临其境的体验能…

(资料收藏)王阳明传《知行合一》共74讲,王阳明知行合一音频讲解资料

今天给大家带来的不是软件,而是一份精神食粮——《知行合一》的教程福利。这可不是一般的教程,它关乎心灵,关乎智慧,关乎我们如何在纷繁复杂的世界中找到自己的位置。 咱们得聊聊王阳明,这位明代的大儒,他…

餐饮业应该购置精酿啤酒设备吗?

近几年,啤酒行业刮起了一股“精酿风”,它不只是一种饮品口味上的变化,更像是一个生活方式的升级。精酿啤酒的兴起,不仅体现在味道的多样性和层次感上,更重要的是它代表了一种生活态度,是对品质生活的追求。…