怎么从零编写一个 v3 版本的 chrome 浏览器插件实现 CSDN 博客网站的暗黑和明亮主题切换?
整體效果
流沙插件主題切換演示:https://live.csdn.net/v/228888
源碼
https://github.com/kaimo313/quicksand
實(shí)現(xiàn)步驟
1、新建 manifest.json 文件
新建一個(gè) chrome 文件夾,在文件夾里新建 manifest.json 文件,在文件里輸入下面代碼,給插件取名叫流沙,版本是 1.0。
{"name": "流沙","version": "1.0","manifest_version": 3 }這里需要注意的是 manifest_version 必須是整數(shù) 2 或者 3,我們這里使用 3。
2023 年 1 月后 MV2 插件不能再繼續(xù)更新,MV2 插件將不能在 Chrome 中運(yùn)行;2023 年 6 月后 即使使用企業(yè)策略,MV2 擴(kuò)展程序也不再在 Chrome 中運(yùn)行。目前已經(jīng)不能再發(fā)布 MV2 版本的插件,相比于 MV2,MV3 有諸多不同,例如權(quán)限控制,API 的變動(dòng),發(fā)起請求的方式等。
2、將插件添加到擴(kuò)展程序中
打開 chrome 瀏覽器,輸入 chrome://extensions/,點(diǎn)擊加載已解壓的擴(kuò)展程序,選擇剛剛新建的 chrome 文件夾即可。
選擇好文件夾之后,流沙這個(gè)插件就被加載到瀏覽器中了。
3、配置 service-worker.js
background script 是擴(kuò)展的事件處理程序;它包含對擴(kuò)展很重要的瀏覽器事件的偵聽器。它處于休眠狀態(tài),直到觸發(fā)事件,然后執(zhí)行指示的邏輯。有效的后臺腳本僅在需要時(shí)加載,并在空閑時(shí)卸載。
先在 manifest.json 配置:
{"name": "流沙","version": "1.0","manifest_version": 3,"background": {"service_worker": "service-worker.js"} }跟 manifest.json 同級新建 service-worker.js 文件,里面添加下面代碼
console.log("流沙---> service-worker", chrome);chrome.action.onClicked.addListener(function () {console.log('點(diǎn)擊了流沙插件圖標(biāo)'); });然后我們刷新擴(kuò)展程序頁面,發(fā)現(xiàn)有個(gè)錯(cuò)誤
錯(cuò)誤如下:Uncaught TypeError: Cannot read properties of undefined (reading 'onClicked'),沒有onClicked方法
chrome.action 文檔:必須在 manifest 中聲明才能使用此 api
在 manifest 中配置 action
{"name": "流沙","version": "1.0","manifest_version": 3,"background": {"service_worker": "service-worker.js"},"action": {} }刷新清除掉錯(cuò)誤之后,點(diǎn)擊 Service Worker,就可以看到打印的日志
點(diǎn)擊右上角的流沙插件,就會(huì)打印日志出來。
如果沒有這個(gè)圖標(biāo)的可以添加上來。
4、實(shí)現(xiàn)點(diǎn)擊插件圖標(biāo)切換主題 icon
manifest.json 配置
{"name": "流沙","version": "1.0","manifest_version": 3,"description": "用于 CSDN 博客網(wǎng)站的暗黑和明亮主題切換","author": "kaimo","background": {"service_worker": "service-worker.js"},"icons": {"16": "icons/logo.png","48": "icons/logo.png", "128": "icons/logo.png"},"action": {"default_icon": {"32": "icons/popup_light_32.png"},"default_title": "流沙:明亮模式"} }service-worker.js 添加代碼
console.log("流沙---> service-worker", chrome);let themeType = "light";chrome.action.onClicked.addListener(function () {console.log('點(diǎn)擊了流沙插件圖標(biāo)');// 修改初始值themeType = themeType === "light" ? "dark" : "light";chrome.action.setIcon({path: "icons/popup_" + themeType + "_32.png"});chrome.action.setTitle({title: themeType === "light" ? "流沙:明亮模式" : "流沙:暗黑模式"}); });添加 icons 文件夾跟圖片
效果如下:
流沙:明亮模式
點(diǎn)擊切換到流沙:暗黑模式
5、讓 CSDN 的網(wǎng)頁加載插件
先匹配 csdn 網(wǎng)站,在 manifest.json 里添加 content_scripts 的配置
"content_scripts": [{"matches": ["https://*.blog.csdn.net/*"],"js": ["content-script.js"]} ]然后新建 content-script.js 文件,添加代碼
alert("匹配到了 CSDN 博客網(wǎng)站")測試效果,訪問 csdn 博客網(wǎng)站的時(shí)候,就會(huì)彈出。其他網(wǎng)址就不會(huì)。
6、插件里實(shí)現(xiàn)樣式主題的切換
我們發(fā)現(xiàn) id 為 userSkin 的 dom 元素的類不同可以顯示不同的主題的效果。
暗黑主題效果:skin-blackwhale user-skin-Black
明亮主題效果:skin-yellow user-skin-White
具體代碼如下:
manifest.json 文件
{"name": "流沙","version": "1.0","manifest_version": 3,"description": "用于 CSDN 博客網(wǎng)站的暗黑和明亮主題切換","author": "kaimo","background": {"service_worker": "service-worker.js"},"icons": {"16": "icons/logo.png","48": "icons/logo.png", "128": "icons/logo.png"},"action": {"default_icon": {"32": "icons/popup_light_32.png"},"default_title": "流沙:明亮模式"},"content_scripts": [{"matches": ["https://*.blog.csdn.net/*"],"js": ["content-script.js"]}],"permissions": ["storage", "tabs"] }service-worker.js 文件
console.log("流沙---> service-worker", chrome);// 設(shè)置主題類型 function setThemeType(type) {chrome.storage.local.set({ theme: type }, () => {console.log('設(shè)置主題模式為:', type);}); }// 通過 tabs 發(fā)送消息改變主題類型 // tabs api,必須被注冊在 manifest 的 permissions 字段中給插件使用,這里不然獲取不到 url。 function changeThemeByTabs(themeType){chrome.tabs.query({}, tabs => {console.log("獲取 tabs", tabs);for (var i = 0; i < tabs.length; i++) {console.log(`tabs[${i}].url`, tabs[i].url);try {const location = new URL(tabs[i].url);const host = location.host;console.log(host, host.includes("blog.csdn.net"));if (host.includes("blog.csdn.net")) {console.log(tabs[i].id, tabs[i], themeType);// 向選項(xiàng)卡發(fā)送消息chrome.tabs.sendMessage(tabs[i].id, {theme: themeType}, response => {// 將打印出"接收到主題切換";console.log(response);});}}catch (e) {console.error("報(bào)錯(cuò)--->", e);}}}); }// 添加插件監(jiān)聽被安裝事件 // 在 onInstalled 監(jiān)聽器內(nèi)部,擴(kuò)展使用 storage API 設(shè)置一個(gè)值。這將允許多個(gè)擴(kuò)展組件訪問該值并進(jìn)行更新。 // 大部分 API,包括 storage api,必須被注冊在 manifest 的 permissions 字段中給插件使用。 chrome.runtime.onInstalled.addListener(() => {console.log("插件已安裝");// 設(shè)置主題類型setThemeType("light"); });// 添加圖標(biāo)點(diǎn)擊事件監(jiān)聽 chrome.action.onClicked.addListener(() => {console.log('1、點(diǎn)擊了流沙插件圖標(biāo)');// 獲取主題類型chrome.storage.local.get(["theme"], res => {console.log("2、緩存的theme", res);let { theme } = res;// 修改初始值theme = theme === "light" ? "dark" : "light";console.log("3、切換 theme 為:", theme);// 設(shè)置圖標(biāo)chrome.action.setIcon({path: "icons/popup_" + theme + "_32.png"});// 設(shè)置titlechrome.action.setTitle({title: theme === "light" ? "流沙:明亮模式" : "流沙:暗黑模式"});// 設(shè)置主題類型setThemeType(theme);// 通過 tabs 發(fā)送消息改變主題類型changeThemeByTabs(theme);}); });content-script.js 文件
console.log("流沙---> content-script", chrome);// 設(shè)置明亮主題 function setLightThemes() {document.getElementById("userSkin").className = "skin-yellow user-skin-White"; }// 設(shè)置暗黑主題 function setDarkThemes() {document.getElementById("userSkin").className = "skin-blackwhale user-skin-Black"; }// 切換主題 function switchThemes(type = "light") {if(type === "dark") {setDarkThemes();} else {setLightThemes();} }// 初始化設(shè)置 chrome.storage.local.get(['theme'], res => {let { theme } = res;console.log("初始化設(shè)置 theme--->", theme);switchThemes(theme); });// 監(jiān)聽消息 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {console.log("監(jiān)聽消息--->", request, sender, sendResponse);// 接收信息返回給發(fā)送方sendResponse("接收到主題切換");const { theme } = request;switchThemes(theme); });說明
目前這里只實(shí)現(xiàn)了博客首頁的部分內(nèi)容樣式,感興趣的可以自己研究完善。
另外就是打包擴(kuò)展程序 crx 文件的生成。第一次可以不用選私有秘鑰 .pem 文件。
瀏覽器會(huì)自動(dòng)生成的
確定就會(huì)生成,不過這個(gè) crx 不能直接放到擴(kuò)展程序里使用。
該擴(kuò)展程序未列在 Chrome 應(yīng)用商店中,并可能是在您不知情的情況下添加的。
參考 manifest.json 所有配置項(xiàng)
官網(wǎng)中給出所有配置項(xiàng):
{// Required - 通俗易懂"manifest_version": 3,"name": "My Extension","version": "versionString",// 『重點(diǎn)』action配置項(xiàng)主要用于點(diǎn)擊圖標(biāo)彈出框,對于彈出框接受的是html文件"action": {"default_title": "Click to view a popup","default_popup": "popup.html"}// 通俗易懂"default_locale": "en","description": "A plain text description","icons": {...},"author": ...,// 『重點(diǎn)』下面將出現(xiàn)的background.js 配置service work"background": {// Required"service_worker": "service-worker.js",},// 『重點(diǎn)』下面將出現(xiàn)content_script.js 應(yīng)用于所有頁面上下文的js"content_scripts": [{"matches": ["https://*.nytimes.com/*"],"css": ["my-styles.css"],"js": ["content-script.js"]}],// 使用/添加devtools中的功能"devtools_page": "devtools.html",/*** 三個(gè)permission* host_permissions - 允許使用擴(kuò)展的域名* permissions - 包含已知字符串列表中的項(xiàng)目 【只需一次彈框要求允許】* optional_permissions - 與常規(guī)類似permissions,但由擴(kuò)展的用戶在運(yùn)行時(shí)授予,而不是提前授予【安全】* 列出常見選項(xiàng)* {* activeTab: 當(dāng)擴(kuò)展卡選項(xiàng)被改變需要重新獲取新的權(quán)限* tabs: 操作選項(xiàng)卡api(改變位置等)* downloads: 訪問chrome.downloads API 的權(quán)限 便于下載但還是會(huì)受到跨域影響* history: history api權(quán)限* storage: 訪問localstorage/sessionStorage權(quán)限* }*/"host_permissions": ["http://*/*", "https://*/*"],"permissions": ["tabs"],"optional_permissions": ["downloads"],// 內(nèi)部彈出可選頁面 - 見fehelper操作頁"options_page": "options.html","options_ui": {"chrome_style": true,"page": "options.html"}, }參考資料
- 這個(gè)前端的小眾市場蘊(yùn)含著巨大財(cái)富
- 最新版 V3 chrome 插件開發(fā)~ demo + 坑
總結(jié)
以上是生活随笔為你收集整理的怎么从零编写一个 v3 版本的 chrome 浏览器插件实现 CSDN 博客网站的暗黑和明亮主题切换?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抽奖概率算法
- 下一篇: 08 指数基金 定投VS一次性投资