🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
想必各人在网上搜刮办理题目办理方案时都会有如许的履历,明显找到了想要的办理题目的代码,想要一键复制到项目代码中,但有些网页限定了你的复制活动,大概让你登录账号、关注博主,更有甚者直吸收费,此中比如CSDN,以是秉着互联网的开源精力我写个脚原来办理这题目,但由于个游览器的差别本文只针对我经常使用的Chrome游览器举行解说。
开发脚本
根据对CSDN网页结构的相识我们重要针对包裹代码的 和 标签,另有网页对用户复制操纵的监听的处置惩罚。- // ==UserScript==
- // @name 终极复制解锁(捕获阶段拦截 + 全面清理)
- // @namespace http://tampermonkey.net/
- // @version 1.6
- // @description 彻底解除复制限制,包括 pre > code 无法复制的问题
- // @author You
- // @match *://*/*
- // @grant none
- // @run-at document-start
- // ==/UserScript==
- (function() {
- 'use strict';
- // 需要拦截的事件类型(这些事件常被用于限制复制)
- const BLOCKED_EVENTS = [
- 'copy', 'cut', 'selectstart', 'contextmenu', 'selectionchange', 'mousedown', 'mouseup'
- ];
- console.log(`脚本启动`);
- // ---------- 1. 捕获阶段拦截事件传播,但不阻止默认行为 ----------
- function stopPropagationOnly(e) {
- e.stopPropagation(); // 阻止事件传播到页面注册的监听器
- // 不调用 preventDefault,保证浏览器的默认复制行为能执行
- }
- BLOCKED_EVENTS.forEach(eventType => {
- document.addEventListener(eventType, stopPropagationOnly, true); // 捕获阶段
- window.addEventListener(eventType, stopPropagationOnly, true);
- });
- // ---------- 2. 拦截后续 addEventListener 调用 ----------
- const originalAddEventListener = EventTarget.prototype.addEventListener;
- EventTarget.prototype.addEventListener = function(type, listener, options) {
- if (BLOCKED_EVENTS.includes(type)) {
- console.log(`[解锁脚本] 已阻止添加事件: ${type}`);
- return; // 忽略添加
- }
- return originalAddEventListener.call(this, type, listener, options);
- };
- // ---------- 3. 清除已有事件属性和 CSS 限制 ----------
- function removeRestrictions(root) {
- if (!root) return;
- // 兼容 iframe 传入的 window
- if (root.document) root = root.document;
- // 清理 document 对象
- if (root.nodeType === Node.DOCUMENT_NODE) {
- root.oncopy = null;
- root.oncut = null;
- root.onselectstart = null;
- root.oncontextmenu = null;
- root.onselectionchange = null;
- // 添加强制选择样式
- const style = root.createElement('style');
- style.innerHTML = `
- * {
- user-select: text !important;
- -webkit-user-select: text !important;
- -moz-user-select: text !important;
- -ms-user-select: text !important;
- }
- `;
- root.head.appendChild(style);
- } else {
- // 普通元素
- root.oncopy = null;
- root.oncut = null;
- root.onselectstart = null;
- root.oncontextmenu = null;
- root.onselectionchange = null;
- }
- // 处理 Shadow DOM
- if (root.shadowRoot) {
- removeRestrictions(root.shadowRoot);
- }
- // 遍历所有后代元素
- if (root.querySelectorAll) {
- root.querySelectorAll('*').forEach(el => {
- el.oncopy = null;
- el.oncut = null;
- el.onselectstart = null;
- el.oncontextmenu = null;
- el.onselectionchange = null;
- if (el.shadowRoot) {
- removeRestrictions(el.shadowRoot);
- }
- });
- }
- }
- // ---------- 4. 专门处理 pre 和 code 标签:克隆替换以移除所有事件监听器 ----------
- function unlockElements(root) {
- const selectors = ['pre', 'code'];
- selectors.forEach(selector => {
- const elements = root.querySelectorAll(`${selector}:not([data-unlocked])`);
- elements.forEach(el => {
- try {
- const clone = el.cloneNode(true);
- clone.setAttribute('data-unlocked', 'true');
- el.parentNode.replaceChild(clone, el);
- console.log(`[解锁脚本] 已替换 ${selector} 标签,移除了所有事件监听器`);
- } catch (e) {
- console.warn(`[解锁脚本] 替换 ${selector} 失败`, e);
- }
- });
- });
- }
- // 初始执行
- removeRestrictions(document);
- unlockElements(document);
- // ---------- 5. 观察动态添加的内容 ----------
- const observer = new MutationObserver(mutations => {
- mutations.forEach(mutation => {
- mutation.addedNodes.forEach(node => {
- if (node.nodeType === Node.ELEMENT_NODE) {
- removeRestrictions(node);
- unlockElements(node);
- }
- });
- });
- });
- if (document.body) {
- observer.observe(document.body, { childList: true, subtree: true });
- }
- // ---------- 6. 处理 iframe ----------
- function unlockIframes(root) {
- root.querySelectorAll('iframe').forEach(iframe => {
- try {
- const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
- if (iframeDoc) {
- removeRestrictions(iframeDoc);
- unlockElements(iframeDoc);
- // 为 iframe 建立独立的观察者
- const iframeObserver = new MutationObserver(() => {
- removeRestrictions(iframeDoc);
- unlockElements(iframeDoc);
- });
- if (iframeDoc.body) {
- iframeObserver.observe(iframeDoc.body, { childList: true, subtree: true });
- }
- }
- } catch(e) {
- // 跨域 iframe 忽略
- }
- });
- }
- // 定期扫描 iframe 和重复清理(防止页面动态重置)
- setInterval(() => {
- unlockIframes(document);
- removeRestrictions(document);
- unlockElements(document);
- }, 2000);
- })();
复制代码 运行脚本
脚本开发完了就到了实战的时间了,要在游览器中运行写好的脚本文件,以下提供您两种方式,以下方法方案都必要用户打开Chrome的开发者模式方能使用。
打开Chrome的开发者模式 打开Chrome的开发者模式 打开Chrome的开发者模式 !!!告急的事故说三遍
工具运行
使用Chrome扩展工具 在Chrome扩展应用商城下载Tampermonkey,操纵Tampermonkey新建脚本,将之前写的脚本代码放入新建的脚本文件中,生存完毕后使用以下方法在网页中运行
方法一:通过扩展管理页面开启 "答应用户脚本"
这是 Chrome 138+ 版本的尺度操纵方式
- 进入管理页:在 Chrome 右上角点击拼图图标,找到 Tampermonkey,点击右侧的 三个点,选择 "管理扩展步伐"
- 查找开关:在 Tampermonkey 的详情页面里,向下滑动,找到 "答应用户脚本" 的开关。
- 开启:将其打开,然后完全重启一次 Chrome 欣赏器
方法二:在控制台欺凌实验(假如方法一无效)
假如在详情页找不到上述开关,大概开启后依然无效,可以实验用下令欺凌激活
- 确保开发者模式已开:在地点栏输入 chrome://extensions/ 并回车,确认右上角的 "开发者模式" 处于开启状态
- 粘贴下令:按 F12 打开开发者工具,切换到 Console(控制台) 标签页,将以下代码完备粘贴进去并回车:
- chrome.developerPrivate.updateExtensionConfiguration({
- extensionId: "dhdgffkkebhmkfjojejmpbldmpobfkfo",
- userScriptsAccess: true
- });
复制代码
- 重启:实验完毕后,完全关闭 Chrome 并重新打开,再革新网页试试
直接运行
使用 "代码片断" 生存终极脚本(一劳永逸)
假如你经常必要面对复杂的复制限定(比如你之条件到的 标签题目),每次在控制台输入一大段代码会很贫苦。Chrome 的 "代码片断(Snippets)" 功能可以美满办理这个题目,相称于一个内置的、轻量级的脚本管理器。
- 打开Snippets面板:
- 打开开发者工具(F12)。
- 切换到 Sources(源代码) 标签页。
- 创建并生存脚本:
- 点击 "New snippet"(新建代码片断) 。
- 将我之前为你提供的谁人增强版终极脚本(包罗了捕获阶段拦截、克隆更换 标签、处置惩罚 Shadow DOM 等功能的完备代码)粘贴到右侧的编辑器中。
- 按 Ctrl+S 生存,你可以给它起个名字,比如 终极复制解锁。
- 运行脚本:
- 以后在任何遇到复制限定的网页,只需打开开发者工具 -> Sources -> Snippets,找到你生存的脚本,右键点击并选择 "Run"(运行) ,大概点击右下角的运行按钮(一个雷同播放键的图标)即可。
如许,你就拥有了一个不必要 Tampermonkey 也能随时调用的 "终极解锁工具"。
假如对您有所资助,接待您点个关注,我会定时更新技能文档,各人一起讨论学习,一起进步。
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |