從零開發一個 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: 'http://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: 'http://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(info.selectionText), }) }) ```
調試方式
| 文件類型 | 調試方式 | 圖片説明 |
| ----------------- | ------------------------------------------ | ------------------------------------------------------------ |
| content_scripts
| 打開 Console
,如圖切換 | |
|
popup
| 鼠標右鍵點擊擴展圖標,然後點擊審查彈出內容 | |
|
background
| 擴展管理頁點擊Service Worker
即可 | |