您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Ctrl+点击/右键复制,自动附带来源 + 弹窗预览 + 历史记录
当前为
// ==UserScript== // @name 万能复制插件(预览 + 历史) // @namespace http://tampermonkey.net/ // @version 5.0 // @description Ctrl+点击/右键复制,自动附带来源 + 弹窗预览 + 历史记录 // @author You // @match *://*/* // @grant GM_setClipboard // @grant GM_registerMenuCommand // ==/UserScript== (function () { 'use strict'; const allowTags = ['div', 'span', 'p', 'pre', 'code', 'td', 'input', 'textarea', 'li']; const ignoreTags = ['button', 'a', 'script', 'style', 'footer', 'nav']; const copyHistory = []; let lastRightClickedEl = null; function playSound() { const audio = new Audio("data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YYAAAAA="); audio.play().catch(() => {}); } function highlight(el) { const prev = el.style.backgroundColor; el.style.transition = 'background-color 0.3s'; el.style.backgroundColor = '#ffe08a'; setTimeout(() => el.style.backgroundColor = prev, 1500); } function showTip(text) { const tip = document.createElement('div'); tip.textContent = text; tip.style.cssText = ` position: fixed; top: 20px; right: 20px; background: #28a745; color: white; padding: 8px 14px; border-radius: 6px; z-index: 99999; font-size: 14px; `; document.body.appendChild(tip); setTimeout(() => tip.remove(), 2000); } function preview(text) { const panel = document.createElement('div'); panel.style.cssText = ` position: fixed; bottom: 20px; left: 20px; background: white; color: black; padding: 10px; max-width: 400px; max-height: 200px; overflow: auto; border: 1px solid #aaa; box-shadow: 0 0 10px rgba(0,0,0,0.3); border-radius: 6px; z-index: 100000; font-family: monospace; white-space: pre-wrap; `; panel.textContent = text; document.body.appendChild(panel); setTimeout(() => panel.remove(), 5000); } function getText(el) { const tag = el.tagName.toLowerCase(); if (tag === 'input' || tag === 'textarea') return el.value.trim(); return el.innerText?.trim() || el.textContent?.trim() || ''; } function isCopyable(el) { const tag = el.tagName.toLowerCase(); if (ignoreTags.includes(tag)) return false; return allowTags.includes(tag); } function appendSource(text) { const url = window.location.href; const title = document.title; return `${text}\n\n【来源】${title}\n${url}`; } function copyWithSource(text) { if (!text || !text.trim()) return; const finalText = appendSource(text.trim()); if (navigator.clipboard) { navigator.clipboard.writeText(finalText).then(() => { playSound(); preview(finalText); showTip('已复制(附带来源)'); }).catch(() => { GM_setClipboard(finalText); showTip('兼容复制成功'); }); } else { GM_setClipboard(finalText); showTip('复制成功'); } copyHistory.unshift(finalText); if (copyHistory.length > 10) copyHistory.pop(); } document.addEventListener('click', (e) => { if (!e.ctrlKey) return; let el = e.target; while (el && el !== document.body) { if (isCopyable(el)) { const text = getText(el); if (text) { copyWithSource(text); highlight(el); break; } } el = el.parentElement; } }); let timer = null; document.addEventListener('mousedown', (e) => { let el = e.target; while (el && el !== document.body) { if (isCopyable(el)) { timer = setTimeout(() => { const text = getText(el); if (text) { copyWithSource(text); highlight(el); } }, 600); break; } el = el.parentElement; } }); document.addEventListener('mouseup', () => clearTimeout(timer)); document.addEventListener('mouseleave', () => clearTimeout(timer)); document.addEventListener('contextmenu', (e) => { lastRightClickedEl = e.target; }); GM_registerMenuCommand('📋 复制右键目标内容', () => { if (!lastRightClickedEl) return showTip('无记录'); let el = lastRightClickedEl; while (el && el !== document.body) { if (isCopyable(el)) { const text = getText(el); if (text) { copyWithSource(text); highlight(el); return; } } el = el.parentElement; } showTip('无可复制内容'); }); GM_registerMenuCommand('📑 查看复制历史', () => { alert(copyHistory.slice(0, 5).join('\n---\n')); }); })();