终于不消看到CSDN该死的弹窗限定了

[复制链接]
发表于 5 天前 | 显示全部楼层 |阅读模式
🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣
想必各人在网上搜刮办理题目办理方案时都会有如许的履历,明显找到了想要的办理题目的代码,想要一键复制到项目代码中,但有些网页限定了你的复制活动,大概让你登录账号、关注博主,更有甚者直吸收费,此中比如CSDN,以是秉着互联网的开源精力我写个脚原来办理这题目,但由于个游览器的差别本文只针对我经常使用的Chrome游览器举行解说。
开发脚本

根据对CSDN网页结构的相识我们重要针对包裹代码的 和  标签,另有网页对用户复制操纵的监听的处置惩罚。
  1. // ==UserScript==
  2. // @name         终极复制解锁(捕获阶段拦截 + 全面清理)
  3. // @namespace    http://tampermonkey.net/
  4. // @version      1.6
  5. // @description  彻底解除复制限制,包括 pre > code 无法复制的问题
  6. // @author       You
  7. // @match        *://*/*
  8. // @grant        none
  9. // @run-at       document-start
  10. // ==/UserScript==
  11. (function() {
  12.     'use strict';
  13.     // 需要拦截的事件类型(这些事件常被用于限制复制)
  14.     const BLOCKED_EVENTS = [
  15.         'copy', 'cut', 'selectstart', 'contextmenu', 'selectionchange', 'mousedown', 'mouseup'
  16.     ];
  17.     console.log(`脚本启动`);
  18.     // ---------- 1. 捕获阶段拦截事件传播,但不阻止默认行为 ----------
  19.     function stopPropagationOnly(e) {
  20.         e.stopPropagation(); // 阻止事件传播到页面注册的监听器
  21.         // 不调用 preventDefault,保证浏览器的默认复制行为能执行
  22.     }
  23.     BLOCKED_EVENTS.forEach(eventType => {
  24.         document.addEventListener(eventType, stopPropagationOnly, true); // 捕获阶段
  25.         window.addEventListener(eventType, stopPropagationOnly, true);
  26.     });
  27.     // ---------- 2. 拦截后续 addEventListener 调用 ----------
  28.     const originalAddEventListener = EventTarget.prototype.addEventListener;
  29.     EventTarget.prototype.addEventListener = function(type, listener, options) {
  30.         if (BLOCKED_EVENTS.includes(type)) {
  31.             console.log(`[解锁脚本] 已阻止添加事件: ${type}`);
  32.             return; // 忽略添加
  33.         }
  34.         return originalAddEventListener.call(this, type, listener, options);
  35.     };
  36.     // ---------- 3. 清除已有事件属性和 CSS 限制 ----------
  37.     function removeRestrictions(root) {
  38.         if (!root) return;
  39.         // 兼容 iframe 传入的 window
  40.         if (root.document) root = root.document;
  41.         // 清理 document 对象
  42.         if (root.nodeType === Node.DOCUMENT_NODE) {
  43.             root.oncopy = null;
  44.             root.oncut = null;
  45.             root.onselectstart = null;
  46.             root.oncontextmenu = null;
  47.             root.onselectionchange = null;
  48.             // 添加强制选择样式
  49.             const style = root.createElement('style');
  50.             style.innerHTML = `
  51.                 * {
  52.                     user-select: text !important;
  53.                     -webkit-user-select: text !important;
  54.                     -moz-user-select: text !important;
  55.                     -ms-user-select: text !important;
  56.                 }
  57.             `;
  58.             root.head.appendChild(style);
  59.         } else {
  60.             // 普通元素
  61.             root.oncopy = null;
  62.             root.oncut = null;
  63.             root.onselectstart = null;
  64.             root.oncontextmenu = null;
  65.             root.onselectionchange = null;
  66.         }
  67.         // 处理 Shadow DOM
  68.         if (root.shadowRoot) {
  69.             removeRestrictions(root.shadowRoot);
  70.         }
  71.         // 遍历所有后代元素
  72.         if (root.querySelectorAll) {
  73.             root.querySelectorAll('*').forEach(el => {
  74.                 el.oncopy = null;
  75.                 el.oncut = null;
  76.                 el.onselectstart = null;
  77.                 el.oncontextmenu = null;
  78.                 el.onselectionchange = null;
  79.                 if (el.shadowRoot) {
  80.                     removeRestrictions(el.shadowRoot);
  81.                 }
  82.             });
  83.         }
  84.     }
  85.     // ---------- 4. 专门处理 pre 和 code 标签:克隆替换以移除所有事件监听器 ----------
  86.     function unlockElements(root) {
  87.         const selectors = ['pre', 'code'];
  88.         selectors.forEach(selector => {
  89.             const elements = root.querySelectorAll(`${selector}:not([data-unlocked])`);
  90.             elements.forEach(el => {
  91.                 try {
  92.                     const clone = el.cloneNode(true);
  93.                     clone.setAttribute('data-unlocked', 'true');
  94.                     el.parentNode.replaceChild(clone, el);
  95.                     console.log(`[解锁脚本] 已替换 ${selector} 标签,移除了所有事件监听器`);
  96.                 } catch (e) {
  97.                     console.warn(`[解锁脚本] 替换 ${selector} 失败`, e);
  98.                 }
  99.             });
  100.         });
  101.     }
  102.     // 初始执行
  103.     removeRestrictions(document);
  104.     unlockElements(document);
  105.     // ---------- 5. 观察动态添加的内容 ----------
  106.     const observer = new MutationObserver(mutations => {
  107.         mutations.forEach(mutation => {
  108.             mutation.addedNodes.forEach(node => {
  109.                 if (node.nodeType === Node.ELEMENT_NODE) {
  110.                     removeRestrictions(node);
  111.                     unlockElements(node);
  112.                 }
  113.             });
  114.         });
  115.     });
  116.     if (document.body) {
  117.         observer.observe(document.body, { childList: true, subtree: true });
  118.     }
  119.     // ---------- 6. 处理 iframe ----------
  120.     function unlockIframes(root) {
  121.         root.querySelectorAll('iframe').forEach(iframe => {
  122.             try {
  123.                 const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  124.                 if (iframeDoc) {
  125.                     removeRestrictions(iframeDoc);
  126.                     unlockElements(iframeDoc);
  127.                     // 为 iframe 建立独立的观察者
  128.                     const iframeObserver = new MutationObserver(() => {
  129.                         removeRestrictions(iframeDoc);
  130.                         unlockElements(iframeDoc);
  131.                     });
  132.                     if (iframeDoc.body) {
  133.                         iframeObserver.observe(iframeDoc.body, { childList: true, subtree: true });
  134.                     }
  135.                 }
  136.             } catch(e) {
  137.                 // 跨域 iframe 忽略
  138.             }
  139.         });
  140.     }
  141.     // 定期扫描 iframe 和重复清理(防止页面动态重置)
  142.     setInterval(() => {
  143.         unlockIframes(document);
  144.         removeRestrictions(document);
  145.         unlockElements(document);
  146.     }, 2000);
  147. })();
复制代码
运行脚本

脚本开发完了就到了实战的时间了,要在游览器中运行写好的脚本文件,以下提供您两种方式,以下方法方案都必要用户打开Chrome的开发者模式方能使用。
打开Chrome的开发者模式 打开Chrome的开发者模式 打开Chrome的开发者模式 !!!告急的事故说三遍
工具运行

使用Chrome扩展工具 在Chrome扩展应用商城下载Tampermonkey,操纵Tampermonkey新建脚本,将之前写的脚本代码放入新建的脚本文件中,生存完毕后使用以下方法在网页中运行
方法一:通过扩展管理页面开启 "答应用户脚本"

这是 Chrome 138+ 版本的尺度操纵方式

  • 进入管理页:在 Chrome 右上角点击拼图图标,找到 Tampermonkey,点击右侧的 三个点,选择  "管理扩展步伐"
  • 查找开关:在 Tampermonkey 的详情页面里,向下滑动,找到  "答应用户脚本"  的开关。
  • 开启:将其打开,然后完全重启一次 Chrome 欣赏器 
方法二:在控制台欺凌实验(假如方法一无效)

假如在详情页找不到上述开关,大概开启后依然无效,可以实验用下令欺凌激活 

  • 确保开发者模式已开:在地点栏输入 chrome://extensions/ 并回车,确认右上角的  "开发者模式"  处于开启状态 
  • 粘贴下令:按 F12 打开开发者工具,切换到 Console(控制台)  标签页,将以下代码完备粘贴进去并回车:
  1. chrome.developerPrivate.updateExtensionConfiguration({
  2.     extensionId: "dhdgffkkebhmkfjojejmpbldmpobfkfo",
  3.     userScriptsAccess: true
  4. });
复制代码

  • 重启:实验完毕后,完全关闭 Chrome 并重新打开,再革新网页试试 
直接运行

使用 "代码片断" 生存终极脚本(一劳永逸)

假如你经常必要面对复杂的复制限定(比如你之条件到的  标签题目),每次在控制台输入一大段代码会很贫苦。Chrome 的  "代码片断(Snippets)"  功能可以美满办理这个题目,相称于一个内置的、轻量级的脚本管理器。

  • 打开Snippets面板

    • 打开开发者工具(F12)。
    • 切换到 Sources(源代码)  标签页。

  • 创建并生存脚本

    • 点击  "New snippet"(新建代码片断)
    • 将我之前为你提供的谁人增强版终极脚本(包罗了捕获阶段拦截、克隆更换  标签、处置惩罚 Shadow DOM 等功能的完备代码)粘贴到右侧的编辑器中。
    • 按 Ctrl+S 生存,你可以给它起个名字,比如 终极复制解锁。

  • 运行脚本

    • 以后在任何遇到复制限定的网页,只需打开开发者工具 -> Sources -> Snippets,找到你生存的脚本,右键点击并选择  "Run"(运行) ,大概点击右下角的运行按钮(一个雷同播放键的图标)即可。

如许,你就拥有了一个不必要 Tampermonkey 也能随时调用的 "终极解锁工具"。
假如对您有所资助,接待您点个关注,我会定时更新技能文档,各人一起讨论学习,一起进步。



免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表