简介
Chrome浏览器扩展是Google Chrome浏览器的浏览器扩展程序,可以在以Chrome为内核的浏览器中运行,包括Chrome、Edge等,能够增强Chrome浏览器的功能,通过添加新的按钮、工具栏、侧边栏、选项页等用户界面元素,或者通过修改网页内容、样式和行为,为用户提供更加个性化、高效和便捷的浏览体验。
文件夹内容
├─ CSDN取消关注限制
……..├─ manifest.json
……..├─ background.js
……..├─ content-script.js
……..├─ popup.html
……..├─ popup.js
……..├─ style.css
……..└─ images
manifest.json
manifest.json
是 Chrome 浏览器扩展(以及其他基于 Chromium 的浏览器,如 Edge)的核心文件。它包含了扩展的元数据、版本信息、所需权限、背景脚本、内容脚本等。
当更改 manifest.json
文件后,通常需要重新加载扩展才能看到更改的效果。在 Chrome 中,可以通过“扩展程序”页面(chrome://extensions/)的“重新加载”按钮来做到这一点。
完整的配置文档请戳这里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| { "name": "CNDS无需关注", "description": "解锁关注后查看限制", "version": "0.1.1", "manifest_version": 3,
"icons": { "16": "/images/icon.png", "48": "/images/icon.png", "128": "/images/icon.png" }, "background": { "service_worker": "./background.js" }, "action": { "default_popup": "popup.html", "default_icon ": "/images/icon.png", "default_title": "CNDS无需关注" }, "permissions": [ "storage", "tabs", "scripting", "notifications" ], "host_permissions": [ "<all_urls>", "https://blog.csdn.net/" ] }
|
background.js
background.js
是扩展的后台脚本,它在扩展的生命周期内持续运行,不受页面加载和卸载的影响。它通常用于处理非页面特定的逻辑,如监听浏览器事件、跨页面通信、管理扩展的状态、存储数据等。
在 manifest.json
文件中,background.js
通常被配置在 background
字段中
在Chrome扩展的manifest_version 3
中,持久化后台脚本已被弃用,并鼓励使用事件页面(Event Pages)来替代。事件页面在需要时才被唤醒,这有助于节省系统资源。如果需要后台持续运行的功能,则需要使用服务工作者(Service Workers)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| chrome.runtime.onInstalled.addListener(() => { chrome.storage.local.set({ Enabled: true, Auto_expand: false, Enable_copy: true, Clear_doms: true, }, () => { console.log('OK: Extension is installed!'); }); });
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (/blog.csdn.net/.test(tab.url) && /article/.test(tab.url) && changeInfo.status === "complete") { chrome.scripting.executeScript({ target: { tabId: tabId }, files: ["./content-script.js"], }).then(() => { console.log("INJECTED SCRIPT SUCC."); }).catch((err) => console.log(err)); } });
|
content-script.js
content-script.js
是内容脚本,它会被注入到匹配的页面上下文中执行。内容脚本可以直接访问和操作页面的DOM,因此它们通常用于修改页面内容、监听用户交互、与页面JavaScript交互等。
在 manifest.json
文件中,content.js
通常被配置在 content_scripts
字段中,也可以在background.js
中执行注入content-script.js
操作。
1
| {% fold secondary @展开查看完整代码 %}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| chrome.storage.local.get(['Enabled', 'Auto_expand', 'Enable_copy', 'Clear_doms'], function(value) { if (value.Enabled) { console.log("扩展开始执行");
if (value.Enable_copy) { console.log("执行破解复制"); enableCopy2(); }
console.log("执行破解关注"); if (value.Auto_expand) { expand(); } else { modify(); }
if (value.Clear_doms) { console.log("执行清除弹窗"); removeDoms();
let observer = new MutationObserver((mutationsList) => { for (let mutation of mutationsList) { if (mutation.type == 'childList') { removeDoms(); } } }); observer.observe(document.body, { childList: true }); } } else { console.log("未启用扩展功能"); } });
function modify() { let follow_text = document.getElementsByClassName('follow-text'); if (follow_text.length == 0) { return; } follow_text = follow_text[0]; if (follow_text.textContent == "关注博主即可阅读全文") { follow_text.addEventListener("click", (event) => { event.stopPropagation(); expand(); }); let img = document.getElementsByClassName('chevrondown')[0]; img.addEventListener("click", (event) => { event.stopPropagation(); expand(); }); follow_text.textContent = "关注限制已解锁"; console.log("关注限制已解锁"); } else { console.log("没有找到\"关注博主即可阅读全文\""); } }
function expand() { let article_content = document.getElementById("article_content"); let hide_article_box = document.getElementsByClassName('hide-article-box')[0]; article_content.removeAttribute("style"); hide_article_box.parentElement.removeChild(hide_article_box); console.log("全文展开成功"); }
function removeDoms() { let classes = ['passport-login-tip-container false', 'passport-login-container', 'tool-active-list', 'article-search-tip', 'hljs-button signin active', 'csdn-side-toolbar', 'box-shadow mb8', 'blog-footer-bottom']; let infos = ['右下角弹窗', '登录弹窗', '一键收藏', '黑色提示框', '登录复制提示', '侧边工具栏', '左侧广告', '底部备案信息']; let boxs, box; for (i = 0; i < classes.length; i++) { boxs = document.getElementsByClassName(classes[i]); if (boxs.length > 0) { box = boxs[0]; box.parentElement.removeChild(box); console.log("移除" + infos[i]); } }
let ids = ['toolbarBox', 'asideWriteGuide', 'asideNewNps', 'recommendNps']; let names = ["顶部栏", '左侧广告', '左侧是否推荐','底部是否推荐']; for (i = 0; i < ids.length; i++) { box = document.getElementById(ids[i]); if(box == null) continue; box.parentElement.removeChild(box); console.log("移除" + names[i]); } }
function enableCopy() { function setAllSelect(el = document.body) { for (let index = 0; index < el.children.length; index++) { const e = el.children.item(index); e.style.userSelect = 'text'; setAllSelect(e); } } setAllSelect();
document.body.onkeydown = function(e) { if (e.ctrlKey && e.keyCode == 67) { const pasteText = window.getSelection().toString(); if (null === pasteText || undefined === pasteText || '' === pasteText.trim()) { return; } navigator.clipboard.writeText(pasteText).then(() => { console.log("复制成功!"); }).catch(() => { console.log("复制失败!"); }); } } }
function enableCopy2() { window.oncontextmenu = document.oncontextmenu = document.oncopy = null; var hea = document.getElementsByClassName('toolbar-advert')[0]; if (hea) { hea.remove() }; [...document.querySelectorAll('body')].forEach(dom => dom.outerHTML = dom.outerHTML); [...document.querySelectorAll('body, body *')].forEach(dom => { ['onselect', 'onselectstart', 'onselectend', 'ondragstart', 'ondragend', 'oncontextmenu', 'oncopy'].forEach(ev => dom.removeAttribute(ev)); dom.style['user-select'] = 'auto'; }); }
|
popup.html
通常是一个与浏览器动作(Browser Action)或页面动作(Page Action)关联的弹出窗口的HTML文件。当用户点击扩展时,将显示弹出窗口。用户可在该窗口进行相关设置。
style.css
为样式表文件,用于为网页提供样式信息,控制网页的布局、颜色、字体等视觉表现
扩展中使用 popup.html
,需要在 manifest.json
文件中进行配置。对于浏览器动作,需要设置 browser_action
字段,并指定 default_popup
属性为 popup.html
文件。对于页面动作,则需要设置 page_action
字段。
popup.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="./style.css"> </head> <body> <div align="center"><font size=3 face="黑体">CSDN插件设置</font></div> <div class="option" align="center"> <span class="name">开启插件:</span> <label class="switch"> <input type="checkbox" id="switch-enable" class="checkbox"> </label> </div> <div class="option" align="center"> <span class="name">自动展开:</span> <label class="switch"> <input type="checkbox" id="switch-autoexpand" class="checkbox"> </label> </div> <div class="option" align="center"> <span class="name">破解复制:</span> <label class="switch"> <input type="checkbox" id="switch-enablecopy" class="checkbox"> </label> </div> <div class="option" align="center"> <span class="name">清除弹窗:</span> <label class="switch"> <input type="checkbox" id="switch-clearDom" class="checkbox"> </label> </div> <div align="center"><button id="refresh">刷新网页</button></div> <script src="popup.js"></script> </body> </html>
|
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| html,body{ margin: 0px; width: 200px; height: 100px; font-family: 'Courier New', Courier, monospace; }
.name{ position: relative; margin: 10px 10px 10px 10px; } .checkbox{ position: relative; margin: 10px 10px 10px 10px; }
|
popup.js
通常与popup.html
一起使用,用于处理弹出窗口(Popup)中的用户交互和动态行为。当用户点击浏览器动作(Browser Action)或页面动作(Page Action)的图标时,会打开popup.html
,而popup.js
则负责为其中的元素添加事件监听器、处理用户输入以及与其他部分(如背景脚本或内容脚本)进行通信。
{% fold secondary @展开查看完整代码 %}`1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| const checkBoxs = document.getElementsByClassName("checkbox");
chrome.storage.local.get(['Enabled', 'Auto_expand', 'Enable_copy', 'Clear_doms'], function(value) { checkBoxs[0].checked = value.Enabled; checkBoxs[1].checked = value.Auto_expand; checkBoxs[2].checked = value.Enable_copy; checkBoxs[3].checked = value.Clear_doms; });
checkBoxs[0].addEventListener("change", () => { if (checkBoxs[0].checked) { console.log("启用扩展"); chrome.storage.local.set({ Enabled: true }); } else { console.log("关闭扩展"); chrome.storage.local.set({ Enabled: false }); } chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) { chrome.scripting.executeScript({ target: { tabId: tabs[0].id }, func: refreshPage, }); }); });
checkBoxs[1].addEventListener("change", () => { if (checkBoxs[1].checked) { console.log("启用自动展开"); chrome.storage.local.set({ Auto_expand: true }); } else { console.log("关闭自动展开"); chrome.storage.local.set({ Auto_expand: false }); } });
checkBoxs[2].addEventListener("change", () => { if (checkBoxs[2].checked) { console.log("启用破解复制"); chrome.storage.local.set({ Enable_copy: true }); } else { console.log("关闭破解复制"); chrome.storage.local.set({ Enable_copy: false }); } });
checkBoxs[3].addEventListener("change", () => { if (checkBoxs[3].checked) { console.log("启用清除弹窗"); chrome.storage.local.set({ Clear_doms: true }); } else { console.log("关闭清除弹窗"); chrome.storage.local.set({ Clear_doms: false }); } });
document.getElementById("refresh").onclick = () => { chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) { chrome.scripting.executeScript({ target: { tabId: tabs[0].id }, func: refreshPage, }); }); }
function refreshPage() { window.location.reload(); }
|
`{% endfold %}
分享链接
蓝奏云:https://www.lanzoub.com/iTWzE22lfbxa
密码:9dq3