// ==UserScript== // @name 全局快捷关键词复制·增强存储导出版 // @namespace http://tampermonkey.net/ // @version 3.10 // @description 本地存储、位置记忆、添加/删除/导出关键词 // @match *://*/* // @grant none // @run-at document-idle // @downloadURL https://update.greasyfork.icu/scripts/575523/%E5%85%A8%E5%B1%80%E5%BF%AB%E6%8D%B7%E5%85%B3%E9%94%AE%E8%AF%8D%E5%A4%8D%E5%88%B6%C2%B7%E5%A2%9E%E5%BC%BA%E5%AD%98%E5%82%A8%E5%AF%BC%E5%87%BA%E7%89%88.user.js // @updateURL https://update.greasyfork.icu/scripts/575523/%E5%85%A8%E5%B1%80%E5%BF%AB%E6%8D%B7%E5%85%B3%E9%94%AE%E8%AF%8D%E5%A4%8D%E5%88%B6%C2%B7%E5%A2%9E%E5%BC%BA%E5%AD%98%E5%82%A8%E5%AF%BC%E5%87%BA%E7%89%88.meta.js // ==/UserScript== (function() { 'use strict'; // 存储 KEY const KEY_STORAGE = "quick_copy_keywords"; const POS_STORAGE = "quick_copy_panel_pos"; // 默认关键词 const DEFAULT_KEYWORDS = [ "俄乌战争", "伊朗", "巴以冲突", "叙利亚", "中东局势", "俄罗斯", "乌克兰", "军事新闻", "地缘政治", "美军动态", "北约", "朝鲜", "国际局势", "中国外交", "台海", "日本动态", "韩国新闻", "欧盟", "非洲局势", "拉美动态" ]; // 读取关键词 function getKeys() { try { const data = localStorage.getItem(KEY_STORAGE); return data ? JSON.parse(data) : DEFAULT_KEYWORDS; } catch { return DEFAULT_KEYWORDS; } } // 保存关键词 function saveKeys(arr) { localStorage.setItem(KEY_STORAGE, JSON.stringify(arr)); } // 读取位置 function getPos() { try { return JSON.parse(localStorage.getItem(POS_STORAGE)) || { left: 20, top: 500 }; } catch { return { left: 20, top: 500 }; } } // 保存位置 function savePos(x, y) { localStorage.setItem(POS_STORAGE, JSON.stringify({ left: x, top: y })); } if (document.getElementById('quick-copy-panel')) return; const root = document.createElement('div'); root.id = 'quick-copy-panel'; const pos = getPos(); root.style.cssText = ` all: initial; position: fixed; z-index: 9999999; left: ${pos.left}px; top: ${pos.top}px; width: 220px; font-family: system-ui, sans-serif; user-select: none; `; document.body.appendChild(root); const bar = document.createElement('div'); bar.style.cssText = ` background: #1677ff; color: white; padding: 10px 12px; border-radius: 10px 10px 0 0; font-size: 14px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; cursor: move; `; bar.innerHTML = `快捷复制`; root.appendChild(bar); const panel = document.createElement('div'); panel.id = 'panel-body'; panel.style.cssText = ` background: #ffffff; border-radius: 0 0 10px 10px; padding: 10px; box-shadow: 0 4px 16px rgba(0,0,0,0.15); max-height: 320px; overflow-y: auto; ::-webkit-scrollbar { width: 5px; } ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 5px; } ::-webkit-scrollbar-track { background: #f5f5f5; } `; root.appendChild(panel); const input = document.createElement('input'); input.type = 'text'; input.placeholder = "输入自定义关键词"; input.style.cssText = ` width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid #e0e0e0; border-radius: 6px; font-size: 14px; margin-bottom: 8px; outline: none; `; panel.appendChild(input); const btnGroup = document.createElement('div'); btnGroup.style.display = "flex"; btnGroup.style.gap = "6px"; btnGroup.style.marginBottom = "10px"; const copyBtn = document.createElement('button'); copyBtn.textContent = '复制'; copyBtn.style.cssText = ` flex:1; padding: 8px; background:#1677ff; color:white; border:none; border-radius:6px; cursor:pointer; `; const addBtn = document.createElement('button'); addBtn.textContent = '添加'; addBtn.style.cssText = ` flex:1; padding: 8px; background:#22c55e; color:white; border:none; border-radius:6px; cursor:pointer; `; btnGroup.append(copyBtn, addBtn); panel.appendChild(btnGroup); const list = document.createElement('div'); list.style.cssText = ` display: flex; flex-wrap: wrap; gap: 6px; margin-bottom:10px; `; panel.appendChild(list); const exportBtn = document.createElement('button'); exportBtn.textContent = "导出全部关键词"; exportBtn.style.cssText = ` width:100%; padding:8px; background:#ff4081; color:#fff; border:none; border-radius:6px; cursor:pointer; font-size:13px; `; panel.appendChild(exportBtn); // 渲染列表 function renderList() { list.innerHTML = ""; const keys = getKeys(); keys.forEach((kw, idx) => { const item = document.createElement('div'); item.style.cssText = "position:relative;"; const btn = document.createElement('button'); btn.textContent = kw; btn.style.cssText = ` padding: 6px 20px 6px 10px; border:none; border-radius:6px; background:#f2f2f2; font-size:13px; cursor:pointer; white-space:nowrap; `; btn.onclick = () => { input.value = kw; copyText(kw); }; const del = document.createElement('span'); del.textContent = "×"; del.style.cssText = ` position:absolute; right:4px; top:2px; font-size:12px; color:#999; cursor:pointer; `; del.onclick = (e) => { e.stopPropagation(); keys.splice(idx, 1); saveKeys(keys); renderList(); }; item.appendChild(btn); item.appendChild(del); list.appendChild(item); }); } // 添加 addBtn.onclick = () => { const val = input.value.trim(); if (!val) return tip("请输入关键词"); const list = getKeys(); list.push(val); saveKeys(list); input.value = ""; renderList(); tip("已添加:" + val); }; // 导出 exportBtn.onclick = () => { const arr = getKeys(); const code = "const KEYWORDS = " + JSON.stringify(arr, null, 4) + ";"; navigator.clipboard.writeText(code).then(() => { tip("已复制全部关键词"); }); }; // 折叠 const foldBtn = document.getElementById('fold-btn'); foldBtn.style.cursor = 'pointer'; foldBtn.onclick = () => { const hidden = panel.style.display === 'none'; panel.style.display = hidden ? 'block' : 'none'; foldBtn.textContent = hidden ? '−' : '+'; bar.style.borderRadius = hidden ? '10px' : '10px 10px 0 0'; }; // 复制 function copyText(text) { const textarea = document.createElement('textarea'); textarea.value = text; textarea.style.cssText = 'position:fixed;left:-9999px;top:-9999px;'; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); const tip = document.createElement('div'); tip.textContent = `已复制:${text}`; tip.style.cssText = ` position: fixed; left:50%; bottom:80px; transform:translateX(-50%); background:rgba(0,0,0,0.7); color:white; padding:6px 12px; border-radius:6px; font-size:13px; z-index:99999999; white-space:nowrap; `; document.body.appendChild(tip); setTimeout(() => tip.remove(), 1200); } copyBtn.onclick = () => { const val = input.value.trim(); if (val) copyText(val); }; // 拖拽 + 位置保存 let isDrag = false, startX, startY, origLeft, origTop; bar.addEventListener('mousedown', e => { if (e.target === foldBtn) return; isDrag = false; startX = e.clientX; startY = e.clientY; origLeft = root.offsetLeft; origTop = root.offsetTop; const move = ev => { const dx = ev.clientX - startX; const dy = ev.clientY - startY; if (Math.abs(dx) > 4 || Math.abs(dy) > 4) isDrag = true; root.style.left = origLeft + dx + 'px'; root.style.top = origTop + dy + 'px'; }; const up = () => { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', up); if (isDrag) savePos(root.offsetLeft, root.offsetTop); }; document.addEventListener('mousemove', move); document.addEventListener('mouseup', up); }); function tip(text) { const t = document.createElement('div'); t.textContent = text; t.style.cssText = ` position:fixed; bottom:60px; left:50%; transform:translateX(-50%); background:rgba(0,0,0,0.7); color:#fff; padding:5px 10px; border-radius:4px; font-size:12px; z-index:999999; `; document.body.appendChild(t); setTimeout(() => t.remove(), 1400); } renderList(); // 默认永久折叠 panel.style.display = "none"; foldBtn.textContent = "+"; bar.style.borderRadius = "10px"; })();