从零开发一个 Chrome 扩展程序(自动给网页加个看板娘,盯着你认真工作/摸鱼)
ead>theme: vuepress
前言
本文打算实现一个自动给网页添加一个看板娘的扩展,可以显示/隐藏, 并且有持久化记录功能;根据网页的href
记录是否开启看板娘;以及鼠标选中文本出现扩展自定义的 menu
事件;如图所示:
什么是 Chrome 扩展程序?
Chrome 扩展程序(Chrome-extensions
),也俗称Chrome插件
,下面我简称Chrome扩展
,它可以增强浏览器的功能,让用户对自己的浏览器实现定制化
,DIY
的快乐懂的都懂(DDDD
)
怎样查看自身安装的扩展?
我们可以通过点击 更多工具 -> 扩展程序
来打开扩展程序标签页, 在标签页中查看我们所有安装的扩展,或者在顶部地址栏输入chrome://extensions/
打开。 如图所示:
怎样获取扩展程序?
大多数Chrome
用户从Chrome 应用商店获得扩展程序。世界各地的开发人员会在Chrome应用商店
中发布他们的扩展,经过 Chrome
的审查并最终向用户提供
-
由于一些众所周知的原因,我们并不能访问
Chrome应用商店
, 但是Chrome
又要求扩展
必须从它的Chrome应用商店
下载安装,这成了一个死循环,不过只要思想不滑坡,方法总比困难多
,下面我会讲解如何从本地加载扩展, -
我们只要在能访问的网站上extfans.com下载需要的扩展,再打开
扩展程序标签页
,打开右上角的开发者模式
开关,再把下载好的压缩包解压,解压后会看到一个.crx
后缀的文件,将文件拖拽到扩展程序标签页
即可。
开始
实现简易 demo
我们新建一个文件夹demo
,在文件夹内创建一个manifest.json
配置文件:
json
{
// manifest的版本号,主流是2,在2024年彻底不支持,最新版本是3,
"manifest_version": 3,
// 扩展名称
"name": "看板娘",
// 扩展版本
"version": "1.0.0",
// 扩展描述
"description": "给页面加入一个看板娘,盯着你认真工作!"
}
manifest_version
版本号 2
跟 3
的 API 会有较大差别;请注意区分:
扩展可以点击右上角扩展图标来弹出一个小窗口的页面,焦点离开时窗口页面关闭,一般做一些临时性的交互操作;在配置文件中新增 icon
字段,配置图标,新增 action
字段,配置 popup
弹框:
json
{
"manifest_version": 3,
"name": "看板娘",
"version": "1.0.0",
"description": "给页面加入一个看板娘,盯着你认真工作!",
// 图标,扩展程序列表内的图标,我全部用一个尺寸;文章最后会提供资源文件的链接
"icons": {
"16": "img/live2d.png",
"48": "img/live2d.png",
"128": "img/live2d.png"
},
// 右上角图标、可根据规则高亮或置灰: 默认高亮
"action": {
"default_icon": "img/live2d.png",
"default_title": "这是自己开发的一个Chrome扩展",
"default_popup": "html/popup.html"
}
}
我们创建一下popup.html
```html
我是你点击出来的popup页面
```
提示: 我们在
扩展程序标签页
记得打开右上角的开发者模式
开关
此时;我们在扩展程序标签页
点击左上角的加载已解压的扩展程序
按钮,找到我们创建的这个demo
文件夹,点击选择文件夹
;扩展便成功出现在你 扩展程序标签页中
;如图所示:
提示:记得开启卡片右下角的开关,下图第二个红框
我们继续点击右上角的扩展程序图标
,会弹出你安装的所有扩展,我们点击第二个红框的图标;扩展便出现在了扩展图标
的左侧; 如下图所示:
点击看板娘图标便出现popup.html
页面;如下图所示:
此时我们便成功开发了一个最简单的Chrome扩展程序
,接下来,我们正式开发标题所说的看板娘扩展
实现看板娘扩展
我们打算在页面中自动生成一个看板娘,那便需要往网页中注入生成看板娘的代码文件
,这需要用到content_scripts
API:
json
{
"content_scripts": [
{
// 匹配规则:匹配所有url
"matches": ["<all_urls>"],
// 多个js会按顺序注入
"js": ["js/live2d.min.js", "js/live2d.0.min.js", "js/init.js"],
// 代码注入的时间,可选值: "document_start", "document_end", "document_idle"
// document_idle 表示页面空闲时; 默认就是document_idle
"run_at": "document_idle"
}
]
}
live2d.min.js
看板娘文件 1live2d.0.min.js
看板娘文件 2init.js
初始化看板娘
```js // init.js
live2dWidget.init({ model: { jsonPath: 'https://unpkg.com/[email protected]/assets/shizuku.model.json', }, display: { superSample: 2, width: 300, height: 400, position: 'left', hOffset: 0, vOffset: 0, }, }) ```
此时,打开任意网页,便能在左下角看到一个可爱的看板娘了。如图所示:
下面我们优化一下这个扩展,目前我们只能无差别的展示看板娘,我们想在右上角的popup.html
页面上控制看板娘的显示/隐藏
,并且显示/隐藏
状态可以被持久化记录;这用到了几个 API:chrome.storage.local
、chrome.tabs.query
、chrome.tabs.sendMessage
由于用到了chrome.storage
, 所以要在 manifest.json
文件中添加以下权限:
json
{
"permissions": ["storage"]
}
下面我们改造一下popup.html
:
```html
看板娘目录
```
```js // popup.js
const GET_LOCATION_HREF = 'get-location-href' const TOGGLE_LIVE2D = 'toggle-live2d' const live2dDom = document.getElementById('switch-live2d')
initLive2dStatus()
/* * 添加change事件 / live2dDom.addEventListener('change', async (event) => { const status = event.target.checked const message = { cmd: TOGGLE_LIVE2D, status, }
const { href } = await sendMessageToInitScript(message) chrome.storage.local.set({ [href + TOGGLE_LIVE2D]: status }) })
/* * 初始化看板娘状态 / async function initLive2dStatus() { const localStorage = await chrome.storage.local.get() const message = { cmd: GET_LOCATION_HREF, storage: localStorage, }
const { href } = await sendMessageToInitScript(message) const status = localStorage[href + TOGGLE_LIVE2D]
if (status) { live2dDom.children[0].checked = true } else { live2dDom.children[0].checked = false } }
/ * 发送消息到init.js * @param {} message * @returns / async function sendMessageToInitScript(message) { const tabList = await chrome.tabs.query({ active: true }) const response = await chrome.tabs.sendMessage(tabList[0].id, message) return response } ```
init.js
修改如下:
```js const GET_LOCATION_HREF = 'get-location-href' const TOGGLE_LIVE2D = 'toggle-live2d'
/* * @description: 初始化 / live2dWidget.init({ // ... })
/* * 在下一轮事件循环动作,确保DOM已经生成 / setTimeout(() => { const href = location.href const status = localStorage.getItem(href + TOGGLE_LIVE2D) toggleLive2d(+status) }, 0)
addListener()
/* * 添加监听 * @returns / function addListener() { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { const { cmd, storage, status } = request const href = location.href
if (cmd === GET_LOCATION_HREF) {
sendResponse({ href })
toggleLive2d(storage[href + TOGGLE_LIVE2D])
return
}
if (cmd === TOGGLE_LIVE2D) {
sendResponse({ href })
toggleLive2d(status)
localStorage.setItem(href + TOGGLE_LIVE2D, +status)
return
}
}) }
/* * 开关看板娘 * @returns / function toggleLive2d(status) { const ele = document.getElementById('live2d-widget')
if (!ele) { console.error('liveDom is undefined') return }
if (status) { ele.style.display = 'block' } else { ele.style.display = 'none' } } ```
到这一步,带有控制开关以及记忆功能的Chrome扩展
便开发完毕了!
自定义浏览器的右键菜单
接下来我们实现一个选中文字调用百度搜索的小功能,这需要用到chrome.contextMenus
API:
manifest.json
文件中需要开启contextMenus
权限background
是一个常驻的页面,它随着浏览器的打开而打开,随着浏览器的关闭而关闭,通常把需要一直运行的、启动就运行的、全局的代码放在background
```json // manifest.json
{ "permissions": ["storage", "contextMenus"], "background": { "service_worker": "js/background.js" } } ```
```js // background.js
chrome.contextMenus.create({ id: chrome.runtime.id, title: '使用看板娘搜索:%s', // %s 表示选中的文本 contexts: ['selection'], // selection 表示选中事件 })
chrome.contextMenus.onClicked.addListener((info, tab) => { chrome.tabs.create({ url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(info.selectionText), }) }) ```
调试方式
| 文件类型 | 调试方式 | 图片说明 |
| ----------------- | ------------------------------------------ | ------------------------------------------------------------ |
| content_scripts
| 打开 Console
,如图切换 | |
|
popup
| 鼠标右键点击扩展图标,然后点击审查弹出内容 | |
|
background
| 扩展管理页点击Service Worker
即可 | |