【教程向】从零开始创建浏览器插件(六)实战篇

【教程向】从零开始创建浏览器插件(六)实战篇

在这篇文章中,我们将详细介绍一个名为“摸鱼King”的Chrome扩展程序的开发思路。这个扩展程序的主要功能是在用户浏览网页时提供便捷的方式来摸鱼看小说。
完整的工程我放在了完整工程,可以下载下来自己试一试。

1. 主要功能和组件

我们以一个摸鱼看小说的插件为例,需要实现导入(存储)小说、选择(读取)小说、设置分页参数、渲染小说文字展示、快捷键等功能。

  • 名称和版本

    • 名称:摸鱼King
    • 版本:1.0
    • 描述:摸鱼看小说
  • 权限需求

    • [activeTab]允许扩展访问当前活动标签页的信息。
    • [storage]允许扩展存储和检索数据。
    • [scripting]允许扩展运行脚本。
  • 背景脚本

    • 使用[background.js]作为服务工作线程,这是manifest v3中推荐的方式,可以有效管理和维护扩展的后台逻辑。
  • 弹出页面

    • 默认弹出页面设置为[popup/popup.html],用户可以通过点击扩展图标来触发这个页面,进行更多交互操作。
  • 内容脚本

    • [content/content.js]在所有网页上运行(由<all_urls>匹配),并在文档加载结束时执行。这允许扩展在网页内容完全加载后修改或访问网页内容。
  • 图标

    • 使用[icon128.png]作为扩展的默认图标,显示在浏览器的扩展栏中。
2. 开发思路

开发这个扩展程序的主要思路是提供一个简单而直接的方式来增强用户的浏览体验,通过在浏览器中直接提供摸鱼看小说的功能。通过内容脚本,扩展可以在用户浏览网页时插入小说内容或相关功能,而不干扰网页的主要功能。

  • 背景脚本处理扩展的核心逻辑,如数据存储和跨标签页的操作。
  • 弹出页面提供用户界面,使用户可以进行简单的交互,如选择小说或调整设置。
  • 内容脚本直接与网页交互,插入或修改网页内容,提供摸鱼功能。
3.项目初始化

由上面的思路我们可以整理出一个项目结构目录以及一个manifest配置文件。

目录结构:

moyuKing/
│
├── manifest.json
│
├── background.js          # 背景脚本
│
├── popup/                 # 弹出页面目录
│   └── popup.html         # 弹出页面HTML
│   └── popup.js         	# 弹出页面JS
│   └──popup.css	       	# 弹出页面CSS
│
├── content/               # 内容脚本目录
│   └── content.js         # 内容脚本
│
└──  icon128.png        # 扩展图标

manifest.json

{"manifest_version": 3,"name": "摸鱼king","version": "1.0","description": "摸鱼看小说","permissions": ["activeTab","storage","scripting"],"background": {"service_worker": "background.js"},"action": {"default_popup": "popup/popup.html","default_icon": {"128": "icon128.png"}},"content_scripts": [{"matches": ["<all_urls>"],"js": ["content/content.js"],"run_at": "document_end"}],"icons": {"128": "icon128.png"}
}
4.background.js

背景脚本主要实现数据存储和另外两个脚本之间的数据通信。
IndexedDB 是一种运行在浏览器中的非关系型数据库,适合于存储大量结构化数据,我们选用它来实现数据存储,以下代码打开数据库、创建对象存储、读写数据以及更新数据等操作。

初始化数据库

IndexedDB的操作首先是创建或打开一个数据库。我们定义了一个IDBUtil对象,封装了与数据库操作相关的方法。

const IDBUtil = {dbName: "myDatabase",storeName: "idStore",version: 1,async openDB() {return new Promise((resolve, reject) => {const request = indexedDB.open(this.dbName, this.version);request.onerror = (event) => reject(event.target.errorCode);request.onupgradeneeded = (event) => {const db = event.target.result;if (!db.objectStoreNames.contains(this.storeName)) {db.createObjectStore(this.storeName, { keyPath: "id" });}};request.onsuccess = (event) => resolve(event.target.result);});},// 其他方法...
};

openDB方法中,我们检查数据库是否存在指定的对象存储,如果不存在,则创建一个新的对象存储。keyPath为对象存储的主键。

数据读写

在IndexedDB中,数据的读写需要通过事务来完成。以下是如何插入和检索数据的示例:

async setId(id) {const db = await this.openDB();const transaction = db.transaction(this.storeName, "readwrite");const store = transaction.objectStore(this.storeName);const request = store.put({ id: "unique", value: id });return new Promise((resolve, reject) => {request.onsuccess = () => resolve();request.onerror = (event) => reject(event.target.errorCode);});
},async getId() {const db = await this.openDB();const transaction = db.transaction(this.storeName, "readonly");const store = transaction.objectStore(this.storeName);const request = store.get("unique");return new Promise((resolve, reject) => {request.onsuccess = (event) => resolve(request.result ? request.result.value : null);request.onerror = (event) => reject(event.target.errorCode);});
},

在这里,setId方法通过事务在对象存储中存储了一个ID值,而getId方法则用来检索这个值。

更新数据

数据的更新可以复用之前的插入逻辑,因为IndexedDB的put方法会替换已有的数据记录:

async updateId(newId) {return this.setId(newId);
},
扩展功能

除了基础的数据库操作,我们还展示了如何在浏览器扩展的background脚本中实现更复杂的逻辑,例如更新页面信息、保存文件内容等。这些操作同样基于IndexedDB事务来实现数据的一致性。

const updatePageInfo = async (id, pageNum, pageSize) => {const db = await openDB();const transaction = db.transaction(["files"], "readwrite");const store = transaction.objectStore("files");const request = store.get(id);request.onsuccess = () => {const data = request.result;data.pageNum = pageNum;data.pageSize = pageSize;store.put(data);};
};

updatePageInfo方法中,我们首先通过ID获取文件记录,然后更新其页码和页面大小信息。

完整代码

除此之外,我们还需要提供几个事件的监听来实现数据通信,完整代码如下:

const IDBUtil = {dbName: "myDatabase",storeName: "idStore",version: 1, // 可以根据需要更新数据库结构时增加版本号// 打开(或初始化)数据库async openDB() {return new Promise((resolve, reject) => {const request = indexedDB.open(this.dbName, this.version);request.onerror = (event) => {console.error("Database error:", event.target.errorCode);reject(event.target.errorCode);};// 第一次创建数据库或版本更新时触发request.onupgradeneeded = (event) => {const db = event.target.result;// 创建一个新的存储对象if (!db.objectStoreNames.contains(this.storeName)) {db.createObjectStore(this.storeName, {keyPath: "id",autoIncrement: false,});}};request.onsuccess = (event) => {console.log("Database opened successfully");resolve(event.target.result);};});},// 设置ID值async setId(id) {const db = await this.openDB();const transaction = db.transaction(this.storeName

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

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

相关文章

树莓派发送指令控制FPGA板子上的流水灯程序

文章目录 前言一、树莓派简介二、整体实现步骤三、树莓派设置四、树莓派串口代码五、Verilog代码5.1 串口接收模块5.2 流水灯模块 六、quartus引脚绑定七、 运行效果总结参考 前言 ​ 本次实验的目的是通过树莓派和FPGA之间的串口通信&#xff0c;控制FPGA开发板上的小灯。实验…

Excel常用操作

计算支付成功率 使用公式 ROUND(B2/C2,4)*100&"%" 字符串拼接 将A1-A10的数字用英文逗号拼接 TEXTJOIN(",",TRUE,A1:A10) 将A1-A10中大于5的数字用英文逗号拼接 ARRAYFORMULA(TEXTJOIN(",",TRUE,IF(A1:A10>5,A1:A10,"")…

未来想从事营销策划类的工作,需要怎么学习?

从事营销策划类的工作&#xff0c;提升和学习主要从以下三个方面&#xff1a; 一、营销底层逻辑的搭建 二、营销系统知识的构建 三、大量营销案例的积累 营销入门&#xff0c;其实大多数人一直都在入门的道路上&#xff0c;每个人都是终身学习者。虽然从事营销工作十年多了…

2024年5月中,AITOP100平台活动专区迎来六场AI大赛盛事!

AITOP100平台的活动专区在2024年5月中旬更新的6场AI大赛来了&#xff01; 随着人工智能技术的飞速发展&#xff0c;AI设计已经成为了创新与创意的新领域。2024年5月中旬&#xff0c;由腾讯研究院、剪映、站酷等互联网大厂主办的6场AI设计大赛震撼来袭&#xff0c;为广大AI设计…

【数据分析面试】43.寻找给小费最多的客人(Python:字典用法)

题目&#xff1a; 寻找给小费最多的客人 &#xff08;Python) 给定两个非空列表user_ids和tips&#xff0c;编写一个名为most_tips的函数&#xff0c;用于找到给小费最多的客户。 示例&#xff1a; 输入&#xff1a; user_ids [103, 105, 105, 107, 106, 103, 102, 108, 1…

Top10+java类

OWASPTOP10 文章目录 OWASPTOP10sql注入(面了几家问了几家)xss是什么SSRF文件上传文件包含漏洞命令执行漏洞代码执行漏洞常见的逻辑漏洞越权漏洞java类问题Java 内存马java反序列化的原理:讲一讲weblogic讲一讲shiro反序列化原理讲一讲fastjson反序列化原理:讲一讲log4j RC…

Springboot 文件传输优化

Spring Boot通过MultipartFile接口简化了文件上传的处理。在Spring MVC中&#xff0c;你可以使用RequestParam注解与MultipartFile一起工作来接收上传的文件。Spring Boot默认配置了文件上传的大小限制&#xff0c;但是你可以通过application.properties进行自定义配置。 # 单个…

短剧看剧系统,当前互联网热门项目工具系统模板。

目录 揭秘爆款神器&#xff1a;短剧看剧系统&#xff0c;让你的内容火遍全网&#xff01; 一、短剧看剧系统&#xff1a;一站式解决方案 二、灵活定价&#xff0c;实现收益最大化 三、高效管理&#xff0c;团队协作更轻松 四、数据驱动&#xff0c;精准把握市场动态 五、智…

设置linux终端用户输入空闲一段时间后就自动断开(linux终端超时自动断开)

在 /etc/profile 中加入TMOUT变量即可。 在文件的最后追加以下两行 export TMOUT600 # 600秒内无操作就断开。 readonly TMOUT # 将变量设置为只读&#xff0c;防止用户更改如图

企业计算机服务器中了rmallox勒索病毒怎么解密,rmallox勒索病毒解密工具流程

在当今数字化时代&#xff0c;越来越多的企业依赖计算机服务器进行办公开展业务&#xff0c;计算机服务器犹如企业的心脏&#xff0c;能够为企业存储许多重要的核心信息&#xff0c;帮助企业有效的开展各项工作业务&#xff0c;提高企业的生产效果&#xff0c;但网络是一把双刃…

springMVC基础使用(示例)

maven依赖&#xff08;javax.servlet-api版本与spring-webmvc班恩要匹配不然会报java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRespons&#xff09;&#xff1a; <dependencies><dependency><groupId>javax.servlet</groupId><arti…

CAN模块开发问题概述

问题一 问题描述 工作环境&#xff1a;ECU外接canoe 操作&#xff1a;使用CANoe模拟发送NM报文&#xff0c;然后停发或者断开CANoe 现象&#xff1a;程序跑死&#xff0c;调用call stack查看压栈情况如下图所示 定位代码如下图所示。可见是由于CAN模块在设置Controller状态时…

计算机毕业设计 | vue+springboot调查问卷管理系统(附源码)

1&#xff0c;研究目的 在进入21世纪以后&#xff0c;互联网得到了蓬勃的发展&#xff0c;电子问卷调查也开始逐渐流行起来。传统纸质问卷和电子问卷相比较后&#xff0c;传统问卷还存在很多弊端&#xff1a; 问卷分发起来比较困难&#xff0c;并且分发试卷耗费大量的金钱和时…

vue3 中vite.config.js相关常用配置详解

base&#xff08;默认为/&#xff09;开发或生产环境服务的公共基础路径。合法的值包括以下几种&#xff1a; 绝对 URL 路径名&#xff0c;例如 /foo/ 部署在根目录下的foo文件下页面路径为&#xff1a; https://foo.com/foo/ 完整的 URL&#xff0c;例如 https://foo.com/&am…

网络安全法中关于网络信息的保护和监管,有哪些规定?

网络安全法作为我们数字时代的重要法律保障&#xff0c;对于网络信息的保护和监管有着明确且详细的规定。这些规定不仅体现了国家对于网络安全的重视&#xff0c;也为我们每个人在数字世界中提供了坚实的法律屏障。 首先&#xff0c;我们来看一个关于网络运营者主体责任的案例。…

np.seterr(divide=‘ignore‘, invalid=‘ignore‘)

这行代码用于设置 NumPy 中的错误处理方式。具体来说&#xff0c;它将在发生除零错误和无效操作错误时忽略这些错误&#xff0c;而不会引发异常。 解释一下参数的含义&#xff1a; divideignore&#xff1a;表示在除零错误发生时忽略该错误。invalidignore&#xff1a;表示在…

vue3组件ref属性用法,动态绑定ref

常见用法 <template><CustomWin ref"sectionRef" class"ref-section"></CustomWin ><button click"xx">点击</button> </template><script setup lang"ts"> import {ref} from vue impor…

uniapp开发安卓app使用文字转语音技术

在 UniApp 开发安卓应用时&#xff0c;要实现文字转语音&#xff08;Text-to-Speech, TTS&#xff09;技术&#xff0c;你可以利用 UniApp 的跨平台能力结合原生模块或第三方服务来实现。以下是一些建议的步骤和方法&#xff1a; 1. 使用 UniApp 原生模块&#xff08;如果支持…

【架构-17】通信系统架构设计理论

通信系统网络架构 1. 局域网网络架构 拓扑结构&#xff1a;星型、总线型、环型、树型。 网络架构&#xff1a;单核心架构&#xff08;结构简单&#xff0c;地理范围受限&#xff09;、双核心架构&#xff08;网络拓扑结构可靠&#xff0c;投资较单核高&#xff09;、环型架构…

更高效的数据交互实现丨 DolphinDB Arrow 插件使用教程

Apache Arrow 是一种跨语言的内存数据交换格式&#xff0c;旨在为用户提供高效的数据结构&#xff0c;以实现在不同的数据处理系统之间共享数据而无需进行复制。它由 Apache 软件基金会开发和维护&#xff0c;目前已经成为许多大型数据处理和分析框架的核心组件之一。在分布式框…