您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动检测并高亮 nodeseek 内的代码块(支持自动语言识别),并添加一个“复制”按钮。
// ==UserScript== // @name nodeseek 自动代码高亮 (Highlight.js + 复制按钮) // @namespace http://tampermonkey.net/ // @version 4.1 // @description 自动检测并高亮 nodeseek 内的代码块(支持自动语言识别),并添加一个“复制”按钮。 // @author 三七 // @match https://*.nodeseek.com/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @connect cdn.jsdelivr.net // @license MIT // ==/UserScript== (function() { 'use strict'; // --- 配置部分 --- const HLJS_CSS_URL = "https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/base16/humanoid-light.min.css"; const HLJS_JS_URL = "https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"; // --- 复制按钮的样式 (完全可自定义) --- GM_addStyle(` pre > code.hljs { position: relative; } .copy-code-button { position: absolute; top: 0.5em; right: 0.5em; padding: 4px 8px; font-size: 12px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; color: #ccc; background-color: #444; border: 1px solid #666; border-radius: 4px; cursor: pointer; opacity: 0; transition: opacity 0.2s ease-in-out, background-color 0.2s, color 0.2s, border-color 0.2s; z-index: 10; } pre:hover .copy-code-button { opacity: 1; } .copy-code-button:hover { background-color: #555; color: #fff; } .copy-code-button.copied { background-color: #28a745; /* 成功时用绿色 */ color: white; border-color: #28a745; } `); // --- 核心逻辑 (loadScript 和 debounce 保持不变) --- let hljsLoaded = false; let hljsLoading = false; function debounce(func, delay) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), delay); }; } function loadScript(url, callback) { if (hljsLoaded) { if (callback) callback(); return; } if (hljsLoading) { document.addEventListener('hljs-loaded', callback, { once: true }); return; } hljsLoading = true; GM_xmlhttpRequest({ method: "GET", url: url, onload: function(response) { const script = document.createElement('script'); script.textContent = response.responseText; document.head.appendChild(script).remove(); hljsLoaded = true; hljsLoading = false; console.log(`[Auto Highlighter] Loaded JS: ${url}`); document.dispatchEvent(new Event('hljs-loaded')); if (callback) callback(); }, onerror: function(response) { console.error(`[Auto Highlighter] Failed to load script ${url}:`, response); hljsLoading = false; } }); } // --- 添加复制按钮的函数 (已修复) --- function addCopyButtons() { document.querySelectorAll('pre > code.hljs').forEach(codeBlock => { if (codeBlock.querySelector('.copy-code-button')) { return; } const button = document.createElement('button'); button.className = 'copy-code-button'; button.textContent = '复制'; // [汉化] 默认文字 button.addEventListener('click', (event) => { // [BUG 修复] // 1. 克隆 codeBlock 节点,这样我们不会影响原始 DOM const codeClone = codeBlock.cloneNode(true); // 2. 从克隆的节点中移除按钮 const buttonInClone = codeClone.querySelector('.copy-code-button'); if (buttonInClone) { buttonInClone.remove(); } // 3. 现在从干净的克隆节点获取文本 const codeToCopy = codeClone.innerText; navigator.clipboard.writeText(codeToCopy).then(() => { button.textContent = '已复制!'; // [汉化] 成功提示 button.classList.add('copied'); setTimeout(() => { button.textContent = '复制'; // [汉化] 恢复默认 button.classList.remove('copied'); }, 2000); }).catch(err => { console.error('复制失败: ', err); button.textContent = '错误'; // [汉化] 失败提示 }); }); codeBlock.appendChild(button); }); } function findAndHighlight() { const codeBlocks = document.querySelectorAll('pre > code:not(.hljs)'); if (codeBlocks.length > 0) { console.log(`[Auto Highlighter] Found ${codeBlocks.length} unhighlighted code blocks.`); loadScript(HLJS_JS_URL, () => { if (typeof hljs !== 'undefined') { console.log('[Auto Highlighter] Highlighting now...'); codeBlocks.forEach(element => { hljs.highlightElement(element); }); console.log('[Auto Highlighter] Highlighting complete.'); addCopyButtons(); } else { console.warn('[Auto Highlighter] hljs not available for highlighting.'); } }); } addCopyButtons(); } // --- 启动逻辑 --- GM_addStyle('@import url("' + HLJS_CSS_URL + '");'); const debouncedFindAndHighlight = debounce(findAndHighlight, 300); setTimeout(findAndHighlight, 100); window.addEventListener('load', findAndHighlight); const observer = new MutationObserver(() => { debouncedFindAndHighlight(); }); observer.observe(document.body, { childList: true, subtree: true }); })();