【教程向】从零开始创建浏览器插件(六)实战篇
【教程向】从零开始创建浏览器插件(六)实战篇
在这篇文章中,我们将详细介绍一个名为“摸鱼King”的Chrome扩展程序的开发思路。这个扩展程序的主要功能是在用户浏览网页时提供便捷的方式来摸鱼看小说。
完整的工程我放在了完整工程,可以下载下来自己试一试。
1. 主要功能和组件
我们以一个摸鱼看小说的插件为例,需要实现导入(存储)小说、选择(读取)小说、设置分页参数、渲染小说文字展示、快捷键等功能。
-
名称和版本:
- 名称:摸鱼King
- 版本:1.0
- 描述:摸鱼看小说
-
权限需求:
- [activeTab]允许扩展访问当前活动标签页的信息。
- [storage]允许扩展存储和检索数据。
- [scripting]允许扩展运行脚本。
-
背景脚本:
- 使用[background.js]作为服务工作线程,这是manifest v3中推荐的方式,可以有效管理和维护扩展的后台逻辑。
-
弹出页面:
- 默认弹出页面设置为[popup/popup.html],用户可以通过点击扩展图标来触发这个页面,进行更多交互操作。
-
内容脚本:
- [content/content.js]在所有网页上运行(由
<all_urls>匹配),并在文档加载结束时执行。这允许扩展在网页内容完全加载后修改或访问网页内容。
- [content/content.js]在所有网页上运行(由
-
图标:
- 使用[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相关文章:
【教程向】从零开始创建浏览器插件(六)实战篇
【教程向】从零开始创建浏览器插件(六)实战篇 在这篇文章中,我们将详细介绍一个名为“摸鱼King”的Chrome扩展程序的开发思路。这个扩展程序的主要功能是在用户浏览网页时提供便捷的方式来摸鱼看小说。 完整的工程我放在了完整工程,可以下载下来自己试一试。 1. 主要功能…...
如何用 OceanBase做业务开发——【DBA从入门到实践】第六期
当应用一款新的数据库时,除了基础的安装部署步骤,掌握其应用开发方法才是实现数据库价值的关键。为此,我们特别安排了5月15日(周三)的《DBA 从入门到实践》第六期课程——本次课程将带大家了解OceanBase数据库的开发流…...
Element-UI快速入门
作者介绍:✌️大厂全栈码农|毕设实战开发,专注于大学生项目实战开发、讲解和毕业答疑辅导。 推荐订阅精彩专栏 👇🏻 避免错过下次更新 Springboot项目精选实战案例 更多项目:CSDN主页YAML墨韵 学如逆水行舟,…...
【JavaWeb】网上蛋糕商城后台-商品管理
概念 本文讲解和实现网上蛋糕商城的后台管理系统中的商品管理功能。 商品列表 点击后台管理系统的head.jsp头部的“商品管理”功能选项,向服务器发送请求/admin/goods_list 因此需要在servlet包中创建AdminGoodsListServlet类,用于获取商品信息列表 …...
Django Admin后台管理:高效开发与实践
title: Django Admin后台管理:高效开发与实践 date: 2024/5/8 14:24:15 updated: 2024/5/8 14:24:15 categories: 后端开发 tags: DjangoAdmin模型管理用户认证数据优化自定义扩展实战案例性能安全 第1章:Django Admin基础 1.1 Django Admin简介 Dj…...
Centos7网卡启动失败(Failed to start LSB: Bring up/down)
好雨知时节 当春乃发生 随风潜入夜 润物细无声 报错内容 启动虚拟机时,Ceotos的虚拟网卡没有一起启动,导致服务无法正常使用 查询网络启动状态 systemctl status network.service报Failed to start LSB: Bring up/down 查看网络启动日志 journalctl…...
【NOIP2008普及组复赛】 题4:立体图
题4:立体图 【题目描述】 小渊是个聪明的孩子,他经常会给周围的小朋友讲些自己认为有趣的内容。最近,他准备给小朋友讲解立体图,请你帮他画出立体图。 小渊有一块面积为mn的矩形区域,上面有mn个边长为1的格子&#…...
【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 删除并获得点数(难度⭐⭐)(76)
1. 题目解析 题目链接:LCR 091. 粉刷房子 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 1. 状态定义 在解决这类问题时,我们首先需要根据题目的具体要求来定义状态。针对房屋粉刷问题&#…...
Windows---CMD常用指令大全
CMD是什么? Windows操作系统中的命令行界面程序,全称为命令提示符 CMD可以干什么? 允许用户在文本界面下输入命令来执行各种操作,如文件管理、系统设置、软件安装等 帮助用户更好地控制和管理Windows系统 windows系统CMD指…...
消息中间件是什么?有什么用?常见的消息中间件有哪些?
1.什么是消息中间件? 消息中间件基于队列模型在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统。 2.现实中的痛点: 1.Http请求基于请求与响应的模型,在高并发的情况下,客户端发送大量的请求达到服务器端…...
富锂锰基材料极具发展潜力 我国产业化进程加速
富锂锰基材料极具发展潜力 我国产业化进程加速 富锂锰基材料以锰元素为主,我国锰资源较丰富,相比于铁锂材料、高镍三元材料,富锂锰基材料具有一定的降本潜力。此外富锂锰基材料在能量密度、充放电倍率等方面也具有明显优势。富锂锰基材料是富…...
聚水潭和金蝶云星空单据接口对接
聚水潭和金蝶云星空单据接口对接 对接系统:金蝶云星空 金蝶K/3Cloud(金蝶云星空)是移动互联网时代的新型ERP,是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”,旨在帮助企业打造…...
OpenAI深夜震撼发布最新模型GPT-4o,送上最快速便捷教程
北京时间5月14日凌晨,有人说OpenAI一夜改变了历史。 在我们的深夜、太平洋时间的上午 10 点,OpenAI 召开春季发布会,公布了最新的GPT-4o模型,o代表Omnimodel(全能模型)。20多分钟的演示直播,展…...
没有申请域名的情况下,用navicat远程连接我们的服务器的Mysql数据库
我们可以根据公网ip用shell来远程连接 首先我们打开自己买的服务器 例如你看这个,就是我们的公网IP 如果服务器里面没有安装mysql数据库的话,那么我们可以用一个轻量级的docker来安装数据库代替一下 我们用docker弄个轻量级的mysql5.7.36,…...
Hive中小文件过多的几种处理方式
1、使用concatenate(只支持RCFile和ORC格式) 2、减少map数量,调整参数:输入合并文件相关的参数 3、减少reduce的数量(例如直接设置reduce为xx个、或者设置reduce的大小,系统自动根据大小确定reduce的个数…...
用户登录认证和权限授权(SpringSecurity、JWT、session)
文章目录 前言一、登录认证1. 问题引入2. Session2.1 实现原理2.2 过滤器Filter2.3 上下文对象 3. JWT3.2 实现步骤3.3 拦截器 HandlerInterceptorAdapter3.4 上下文对象 4. Session VS JWT 二、权限授权1. 权限类型1.1 页面权限(菜单项权限)1.2 ACL模型…...
第十二届蓝桥杯省赛真题 Java A 组【原卷】
文章目录 发现宝藏【考生须知】试题 A: 相乘试题 B: 直线试题 C : \mathrm{C}: C: 货物摆放试题 D: 路径试题 E: 回路计数试题 F : \mathrm{F}: F: 最少砝码试题 G: 左孩子右兄弟试题 H : \mathrm{H}: H: 异或数列试题 I \mathbf{I} I 双向排序试题 J : \mathrm{J}: J: 分…...
工作随机:linux 挂载LVM管理模式的磁盘
文章目录 前言一、创建一个分区二、创建PV三、创建VG四、创建LV五、格式化并挂载目录 前言 在数据库管理中,常有比较头疼的问题,就是一段时间发展后我的磁盘空间不够了,想要扩容原有的目录很是头疼,那么LVM管理的优势就体现出来了…...
打印kafka最近的消息
使用 kafka-run-class 指令,获取topic的最小offset和最大offset #查看各个分区的最小offset(这个意思就是,这个offset之前的消息已经被清除了,现在consumer是从这个offset之后开始消费): ./kafka-run-class.sh kafka.tools.GetOffsetShell …...
e行64位V11.17.4 安卓全局虚拟定位APP
e行最新版11.17.4 支持全局虚拟位置 小米手机 百度地图 高德地图 实测成功 其他app自测 不一定支持所有app 下载:https://www.123pan.com/s/HAf9-tsyCh.html...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
