chrome V3 插件开发 基础
目录
- 准备
- popup
- 通信
- popup 发消息给 background
- popup 发消息给 content
- 长期连接
- 如何页面上添加一个按钮?
- tabs.onUpdated
- content-script.js
- inject.js
- 右键菜单
- chrome.contextMenus
- 举个例子添加
- 关于报错(cannot create item with duplicate id XXX)
小白学习chrome 插件开发,如果有什么不对的,请指教
注意: 用的是 chrome V3
准备
- 创建文件夹
myPlugin
- 在
myPlugin
文件中创建manifest.json
文件 - 在
myPlugin
文件中创建icons
文件文件夹,并且在icons
文件中准备一个图片
- 配置
manifest.json
更多参数配置可以查看官网:Manifest file format
{"name": "插件","version": "1.0","manifest_version": 3,"description": "学习chrome插件开发","author": "chenss","icons": {"16": "icons/logo.png","48": "icons/logo.png", "128": "icons/logo.png"}
}
- 打开
管理扩展插件
,把myPlugin
添加进来就能看到了,如果图标不正确可以点击刷新,如果还不行请检查配置路径
准备工作就到这里了,如果你一切顺利,我们继续吧~
popup
创建 popup.html
和 popup.js
popup.html
<!DOCTYPE html>
<head><meta charset="utf-8" /><body><div>chenss</div></body>
</head>
配置 manifest.json
...
"action": {"default_popup": "popup.html"
}
点击插件,就能弹出一个弹框啦~~~
通信
简单通信使用 runtime.sendMessage()
和 tabs.sendMessage()
发消息,在接收端使用 runtime.onMessage
来接收消息。
在根目录新建content-script.js
,配置 manifest.json
...
"action": {"default_popup": "popup.html"
},
"content_scripts": [{"matches": ["*://*/*","<all_urls>"],"js": ["content-script.js"]}
],
"permissions": ["tabs"]
popup 发消息给 background
在 popup.html
添加按钮
<div><div class="box"><button id="backgroud">给bg发消息</button></div><script src="popup.js"></script>
</div>
popup
和 background
分别添加如下代码
// popup.js
let sendBg = document.getElementById("backgroud");
sendBg.onclick = async function () {const [tab] = await chrome.tabs.query({active:true,currentWindow:true})console.log('p->b,tab',tab)const respone =await chrome.runtime.sendMessage(tab.id)console.log('popup-respone',respone);
}
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {console.log('这是background脚本onMessage', message);sendResponse("收到消息");
});
接下来我们看看效果:
点开这个地方

当然 你也可以使用 chrome.runtime.sendMessage
发消息
// popup.js
let sendBg = document.getElementById("backgroud");
sendBg.onclick = async function () {chrome.runtime.sendMessage({greeting:"hello"}, function(response) {console.log(response);
}

popup 发消息给 content
- 同样在
popup.html
添加按钮 popup
和background
分别添加如下代码
// popup.js
let sendContent = document.getElementById("sendContent");
sendContent.onclick = async function () {const [tab] = await chrome.tabs.query({active:true,currentWindow:true})console.log('p->b,tab',tab)const respone =await chrome.tabs.sendMessage(tab.id, {greeting: "hihihihihi"})console.log('popup-respone',respone);
}
// content-script.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {console.log('这是content-script脚本执行内容');console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension");}
);
随便打开一个网站 你就能看到 输出内容
简单通信就不再这里过多描述了,可以参考这个文章:
Chrome插件:浏览器后台与页面间通信
长期连接
有的时候需要长时间通信,以上方法显然不合适。需要使用 runtime.connect
或 tabs.connect
。
建立连接时,两端都将获得一个 runtime.Port
对象,用来通过建立的连接发送和接收消息。
更多详细内容可以看文档,本次只用runtime.connect
举列子。
- 同样在
popup.html
添加按钮 popup
和background
分别添加如下代码
// popup.js
// 长期链接 发消息给bg
longLink.onclick = async function () {var port = chrome.runtime.connect({ name: "knockknock" });port.postMessage({ joke: "Knock knock" });port.onMessage.addListener(function (msg) {if (msg.question === "Who's there?") port.postMessage({ answer: "Madame" });else if (msg.question === "Madame who?")port.postMessage({ answer: "Madame... Bovary" });});
};
// background.js
chrome.runtime.onConnect.addListener(function(port) {console.assert(port.name === "knockknock");port.onMessage.addListener(function(msg) {console.log('msg',msg);if (msg.joke === "Knock knock")port.postMessage({question: "Who's there?"});else if (msg.answer === "Madame")port.postMessage({question: "Madame who?"});else if (msg.answer === "Madame... Bovary")port.postMessage({question: "I don't get it."});});
});

当从 service worker
向 content scripts
发送建立连接请求时,若目标 tab 中存在多个 iframe ,且 content scripts
注入到了每个 iframe 中,则每个 iframe 中的 runtime.onConnect
事件都会被触发。同样的,也可能会出现多个 iframe 中的runtime.connect()
一起调用的情况。
如何页面上添加一个按钮?
tabs.onUpdated
使用 tabs.onUpdated
, 再次强调一下需要配置permissions: [‘tabs’]
,并且需要重新加载插件,如重新加载还是无法生效,请移除插件重新导入
在background.js
代码如下:
//background.js
chrome.tabs.onUpdated.addListener(async function(tabId,changeInfo,tab){console.log('tabs.onUpdated',tabId,changeInfo,tab);if (!tab.url &&changeInfo.status !=='complete') return;sendContent(tabId,{action:"inject"})
});
content-script.js
// content-script.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {var tmp = document.createElement("script");tmp.src = chrome.runtime.getURL("./inject.js");tmp.setAttribute("type", "text/javaScript");document.head.appendChild(tmp);
});
inject.js
manifest.json
中配置
"web_accessible_resources": [ {"resources": ["inject.js"],"matches": [ "*://*/*" ]}],
“matches”:字符串数组,每个字符串都包含一个匹配模式,指定哪些站点可以访问这组资源。仅使用来源来匹配 URL。例如"matches": [ "http://*/*" ]
这样配置的话,https开头网址的页面上看不到按钮。当然可以利用正则匹配网页地址。
//inject.js
var div_child='<button id="div_child_1" style="width:100px;height:50px;position: absolute;top: 120px;right: 50px;font-size: 24px;">按钮</button>'
var c=document.querySelector("body > div");
c.innerHTML+=div_child;let injectBtn = document.getElementById("div_child_1");
injectBtn.onclick= function(){alert("点击了自定义的按钮")
}
右键菜单
chrome.contextMenus
chrome.contextMenus 文档地址
举个例子添加
background.js
里面添加如下代码
//background.js
chrome.runtime.onInstalled.addListener(() => {createMenus()
});
// 自定义右键菜单
function createMenus() {chrome.contextMenus.create({title: "菜单1", //菜单的名称id: '01', //一级菜单的idcontexts: ['page'], // page表示页面右键就会有这个菜单,如果想要当选中文字时才会出现此右键菜单,用:selection});chrome.contextMenus.create({title: '子菜单1', //菜单的名称id: '0101',//二级菜单的idparentId: '01',//表示父菜单是“右键快捷菜单”contexts: ['page'],});chrome.contextMenus.create({title: '菜单2', //菜单的名称id: '02',contexts: ['page'],});}

这样就添加成功了
关于报错(cannot create item with duplicate id XXX)
例如:一开始的时候在onUpdated
周期添加菜单
chrome.tabs.onUpdated.addListener(async function(tabId,changeInfo,tab){chrome.contextMenus.create({...})
});
每次刷新页面的时候就会出现这个重复添加的错误:
是因为 onUpdated
状态是loading 和 complate 的时候重复添加了,当然可以判断一下加载状态,再去创建。
如果你通过通信方式
添加菜单也需要注意,也会存在这个问题。
关于这个文档里有说(使用此事件(onInstalled)可以设置状态或进行一次性初始化,例如上下文菜单。):
未完待续👻👻👻👻👻👻👻👻
相关文章:

chrome V3 插件开发 基础
目录 准备popup通信popup 发消息给 backgroundpopup 发消息给 content长期连接 如何页面上添加一个按钮?tabs.onUpdatedcontent-script.jsinject.js 右键菜单chrome.contextMenus举个例子添加关于报错(cannot create item with duplicate id XXX…...

【uniapp】uniapp自动导入自定义组件和设置分包:
文章目录 一、自动导入自定义组件:二、设置分包和预加载: 一、自动导入自定义组件: 【Volar 官网】https://github.com/vuejs/language-tools 二、设置分包和预加载: 【官方文档】https://uniapp.dcloud.net.cn/collocation…...
【深度学习MOT videos detect】Detect to Track and Track to Detect
论文:https://arxiv.org/abs/1710.03958 代码:https://github.com/feichtenhofer/Detect-Track 文章目录 Abstract1. Introduction2. Related work后面翻译略 Abstract 近期用于在视频中高精度检测和跟踪目标类别的方法越来越复杂,每年都变得…...

关于Neo4j的使用及其基本命令
关于Neo4j的使用 文章目录 关于Neo4j的使用1、启动方式2、创建新节点,节点内有属性3、创建关系4、查询节点5、查询关系6、删除两个节点的关系7、删除节点8、删除某个标签的全部关系9、某个节点添加属性10、删除节点某个属性 1、启动方式 进入bin目录: …...

【笔记】树状数组
【笔记】树状数组 目录 简介引入1. 直接暴力2. 维护前缀和数组总结 定义前置知识: lowbit \operatorname{lowbit} lowbit 操作区间的表示方法操作单点修改前缀和查询任意区间查询 例题1: 单点修改,区间查询例题2: 区间修改,单点查询例题3:…...

vue全局组件自动注册直接使用,无需单独先引用注册再使用
目录结构: 本案例是在根目录下components文件夹测试的,文件位置项目内任意,确保在main.js挂载路径正确即可 1、新建文件夹(名字随意)zxy_components (放自己组件的地方) 2、在zxy_components文件夹下 !新建…...
【HarmonyOS】@ohos.request 上传下载的那些事儿
【关键字】 ohos.request、上传下载 【写在前面】 在进行HarmonyOS应用开发时,可能需要进行上传或下载文件功能开发,本文章主要进行上传下载相关功能介绍和一些注意事项及FAQ。 【上传开发步骤】 步骤1:上传下载接口需要申请ohos.permis…...

github版面混乱加载不出的解决办法
最近出现打开github 界面加载不成功,网页访问乱码,打开chrome的检查发现 github的github.githubassets.com 拒绝访问, 解法: 1.先打开hosts文件所在的目录C:\Windows\System32\drivers\etc 2.右键点击hosts文件-选择用记事本或者…...

dotNet 之数据库sqlite
Sqlite3是个特别好的本地数据库,体积小,无需安装,是写小控制台程序最佳数据库。NET Core是同样也是.NET 未来的方向。 **硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 D…...

走近ChatGPT与类似产品:原理解析与比较
目录 1. 引言1.1 技术的进步与自然语言处理1.2 ChatGPT的崭新概念 2. ChatGPT: 一览众山小2.1 GPT-3.5架构简介2.2 ChatGPT的学习与训练2.3 文本生成的工作原理 3. 市场上类似产品调研3.1 对话式人工智能产品分类3.2 文心一言3.3 讯飞星火 4. 应用前景与局限性展望4.1 ChatGPT的…...

HarmonyOS SDK开放能力,服务鸿蒙生态建设,打造优质应用体验
华为开发者大会2023(HDC.Together)于8月4日至6日在东莞松山湖举行,在HarmonyOS端云开放能力技术分论坛上,华为为广大开发者们介绍了HarmonyOS SDK开放能力在基础开发架构、功能特性等方面的变化之处,通过将常见的通用能…...

数字经济对产业结构升级和创业增长的影响(2011-2021年)
参照刘翠花(2022)的做法,对来自中国人口科学《数字经济对产业结构升级和创业增长的影响》一文中的基准回归部分进行复刻。文章从理论层面分析数字经济发展对产业结构升级、创业增长的影响及其机理,并利用2011-2021年中国省级面板数…...

GPT-4助力数据分析:提升效率与洞察力的未来关键技术 | 京东云技术团队
摘要 随着大数据时代的到来,数据分析已经成为企业和组织的核心竞争力。然而,传统的数据分析方法往往无法满足日益增长的数据分析需求的数量和复杂性。在这种背景下,ChatGPT-4作为一种先进的自然语言处理技术,为数据分析带来了革命…...

Zabbix6 对接飞书告警
文章目录 Zabbix对接飞书告警背景创建飞书群组Zabbix配置创建告警媒介类型创建动作用户关联飞书告警 Zabbix对接飞书告警 背景 运维 你看下他的进程是不是挂了,之前在9点28分有发消息的,这次没有发消息 哐哐哐的去看了一通,确实有个进程之前…...

Javascript异步编程的4种方法
你可能知道,Javascript语言的执行环境是"单线程"(single thread)。 所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一…...

【MySQL】表的内外连接
目录 一、内连接 二、外连接 1、左外连接 2、右外连接 一、内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。 语法: select 字段 from 表1 i…...

详解Mysql——第一篇/连接查询
mysql的连接查询,相必在网上都能找到很多的教程,博主今天不做老话常谈,不走重复路线 1.建表 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id) – –课程编…...
uniapp获取屏幕宽度时 获取不到移动设备中内容盒子宽度
首先 :我使用的是uniapp vue3语法: 问题: 我出现这个问题是IOS 设备发现的,data.boxWidth为0 代码: const initCreated () > {const query uni.createSelectorQuery().in(instance.proxy);const el query.select…...
篇十二:代理模式:控制对象访问
篇十二:“代理模式:控制对象访问” 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 另外有2本不错的关于设计模式的资料,…...
P1657 选书
1:思路:一看数据,嗯....!,爆搜嘛?,看一眼题目,嗯!!!,爆搜! 配上俺的无敌小剪枝,按下拿下! 2:暴力枚举每个人获…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...