從零開發一個 Chrome 擴展程序(自動給網頁加個看板娘,盯着你認真工作/摸魚)

語言: CN / TW / HK
ead>

theme: vuepress

前言

本文打算實現一個自動給網頁添加一個看板孃的擴展,可以顯示/隱藏, 並且有持久化記錄功能;根據網頁的href記錄是否開啟看板娘;以及鼠標選中文本出現擴展自定義的 menu事件;如圖所示:

demo.png

什麼是 Chrome 擴展程序?

Chrome 擴展程序(Chrome-extensions),也俗稱Chrome插件,下面我簡稱Chrome擴展,它可以增強瀏覽器的功能,讓用户對自己的瀏覽器實現定製化DIY的快樂懂的都懂(DDDD

怎樣查看自身安裝的擴展?

我們可以通過點擊 更多工具 -> 擴展程序來打開擴展程序標籤頁, 在標籤頁中查看我們所有安裝的擴展,或者在頂部地址欄輸入chrome://extensions/打開。 如圖所示:

chrome_home.jpg

怎樣獲取擴展程序?

大多數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版本號 23 的 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

Document

我是你點擊出來的popup頁面

```

提示: 我們在擴展程序標籤頁記得打開右上角的 開發者模式 開關

此時;我們在擴展程序標籤頁點擊左上角的加載已解壓的擴展程序按鈕,找到我們創建的這個demo文件夾,點擊選擇文件夾;擴展便成功出現在你 擴展程序標籤頁中;如圖所示:

提示:記得開啟卡片右下角的開關,下圖第二個紅框

add_button.png

我們繼續點擊右上角的擴展程序圖標,會彈出你安裝的所有擴展,我們點擊第二個紅框的圖標;擴展便出現在了擴展圖標的左側; 如下圖所示:

icon_list.jpg

點擊看板娘圖標便出現popup.html頁面;如下圖所示:

popup.jpg

此時我們便成功開發了一個最簡單的Chrome擴展程序,接下來,我們正式開發標題所説的看板娘擴展

實現看板娘擴展

我們打算在頁面中自動生成一個看板娘,那便需要往網頁中注入生成看板孃的代碼文件,這需要用到content_scriptsAPI:

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 看板娘文件 1
  • live2d.0.min.js 看板娘文件 2
  • init.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, }, }) ```

此時,打開任意網頁,便能在左下角看到一個可愛的看板娘了。如圖所示:

demo_baidu.png

下面我們優化一下這個擴展,目前我們只能無差別的展示看板娘,我們想在右上角的popup.html頁面上控制看板孃的顯示/隱藏,並且顯示/隱藏狀態可以被持久化記錄;這用到了幾個 API:chrome.storage.localchrome.tabs.querychrome.tabs.sendMessage

由於用到了chrome.storage, 所以要在 manifest.json文件中添加以下權限:

json { "permissions": ["storage"] }

下面我們改造一下popup.html:

```html

Document

看板娘目錄

顯示/隱藏

```

```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擴展便開發完畢了!

自定義瀏覽器的右鍵菜單

context_menus.png

接下來我們實現一個選中文字調用百度搜索的小功能,這需要用到chrome.contextMenusAPI:

  • 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,如圖切換 | console.png | | popup | 鼠標右鍵點擊擴展圖標,然後點擊審查彈出內容 | popup_right.png | | background | 擴展管理頁點擊Service Worker即可 |background.png |

結束