您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
专门用于查找页面关键词,优化了特殊字符处理
// ==UserScript== // @name 关键词查找工具 // @namespace http://tampermonkey.net/ // @version 0.4 // @description 专门用于查找页面关键词,优化了特殊字符处理 // @author 八千xmx // @match *://*/* // @grant GM_setClipboard // @grant GM_addStyle // @license GNU GPLv3 // ==/UserScript== (function() { 'use strict'; // 添加全局样式 GM_addStyle(` .trade-search-container { position: fixed; bottom: 20px; right: 20px; width: 350px; max-height: 40px; overflow: hidden; transition: all 0.3s ease; border-radius: 6px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); z-index: 9999; font-family: -apple-system, BlinkMacSystemFont, sans-serif; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(8px); border: 1px solid rgba(0,0,0,0.08); } .trade-search-container.expanded { max-height: 400px; } .trade-search-header { padding: 10px 12px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; font-size: 14px; font-weight: 500; background: rgba(0,0,0,0.03); } .trade-search-content { padding: 12px; overflow-y: auto; max-height: 330px; } .trade-search-input { width: 100%; padding: 8px 10px; margin-bottom: 10px; box-sizing: border-box; border: 1px solid rgba(0,0,0,0.1); border-radius: 4px; font-size: 13px; background: rgba(255,255,255,0.8); } .trade-search-results { font-size: 13px; line-height: 1.5; white-space: pre-wrap; max-height: 250px; overflow-y: auto; padding: 5px 0; font-family: monospace; } .trade-search-match { background: rgba(255, 235, 59, 0.35); padding: 0 2px; border-radius: 2px; margin: 2px 0; color: #d32f2f; font-weight: bold; } .trade-search-buttons { display: flex; gap: 8px; margin-top: 10px; } .trade-search-button { flex: 1; padding: 8px; border: none; border-radius: 4px; font-size: 13px; cursor: pointer; transition: all 0.2s; } .trade-search-button.search { background: #4CAF50; color: white; } .trade-search-button.copy { background: #2196F3; color: white; } .trade-search-count { font-size: 12px; color: #666; margin-top: 5px; text-align: right; } .trade-search-toggle { transition: transform 0.2s; } .trade-search-options { display: flex; align-items: center; margin-bottom: 10px; font-size: 12px; } .trade-search-checkbox { margin-right: 5px; } .trade-search-label { margin-right: 15px; display: flex; align-items: center; } `); // 创建容器 const container = document.createElement('div'); container.className = 'trade-search-container'; container.innerHTML = ` <div class="trade-search-header"> <span>数据查找</span> <span class="trade-search-toggle">▼</span> </div> <div class="trade-search-content"> <input type="text" class="trade-search-input" placeholder="输入关键词(如'身高')..."> <div class="trade-search-options"> <label class="trade-search-label"> <input type="checkbox" class="trade-search-checkbox" checked> 中文匹配 </label> <label class="trade-search-label"> <input type="checkbox" class="trade-search-checkbox"> 精确匹配 </label> </div> <div class="trade-search-buttons"> <button class="trade-search-button search">查找</button> <button class="trade-search-button copy">复制</button> </div> <div class="trade-search-results"></div> <div class="trade-search-count"></div> </div> `; document.body.appendChild(container); const header = container.querySelector('.trade-search-header'); const content = container.querySelector('.trade-search-content'); const input = container.querySelector('.trade-search-input'); const searchBtn = container.querySelector('.trade-search-button.search'); const copyBtn = container.querySelector('.trade-search-button.copy'); const results = container.querySelector('.trade-search-results'); const countDisplay = container.querySelector('.trade-search-count'); const toggle = container.querySelector('.trade-search-toggle'); const chineseCheckbox = container.querySelector('.trade-search-checkbox'); const exactCheckbox = container.querySelectorAll('.trade-search-checkbox')[1]; // 查找数据中的关键词 function searchInTrades(keyword) { if (!keyword) { results.innerHTML = '<div style="color:#666">请输入关键词</div>'; countDisplay.textContent = ''; return; } const selection = window.getSelection(); let currentElement = selection.anchorNode; if (!currentElement || currentElement.nodeType !== Node.TEXT_NODE) { currentElement = document.body; } else { currentElement = currentElement.parentElement; } const text = currentElement.textContent; const useChinese = chineseCheckbox.checked; const exactMatch = exactCheckbox.checked; let regex; if (exactMatch) { regex = new RegExp(`(${escapeRegExp(keyword)})`, 'g'); } else if (useChinese) { // 专门匹配中文字符 regex = new RegExp(`([^\\p{P}\\s]*${escapeRegExp(keyword)}[^\\p{P}\\s]*)`, 'gu'); } else { regex = new RegExp(`(\\b[^\\s]*${escapeRegExp(keyword)}[^\\s]*\\b)`, 'gi'); } const matches = [...text.matchAll(regex)]; const uniqueMatches = [...new Set(matches.map(m => m[0]))]; if (uniqueMatches.length > 0) { const highlighted = uniqueMatches.map(match => match.replace(new RegExp(escapeRegExp(keyword), 'gi'), '<span class="trade-search-match">$&</span>') ).join('<br>'); results.innerHTML = highlighted; countDisplay.textContent = `找到 ${uniqueMatches.length} 个唯一匹配`; // 自动滚动到第一个匹配项 const firstMatch = results.querySelector('.trade-search-match'); if (firstMatch) { firstMatch.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } } else { results.innerHTML = `<div style="color:#666">未找到"${keyword}"</div>`; countDisplay.textContent = ''; } } function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // 自动收缩功能 let collapseTimer; container.addEventListener('mouseleave', () => { collapseTimer = setTimeout(() => { container.classList.remove('expanded'); toggle.textContent = '▼'; toggle.style.transform = 'rotate(0deg)'; }, 1000); }); container.addEventListener('mouseenter', () => { clearTimeout(collapseTimer); }); // 点击标题切换展开/收缩 header.addEventListener('click', () => { container.classList.toggle('expanded'); const isExpanded = container.classList.contains('expanded'); toggle.textContent = isExpanded ? '▲' : '▼'; toggle.style.transform = isExpanded ? 'rotate(180deg)' : 'rotate(0deg)'; if (isExpanded) { input.focus(); } }); // 事件监听 searchBtn.addEventListener('click', () => { searchInTrades(input.value.trim()); }); input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { searchInTrades(input.value.trim()); } }); copyBtn.addEventListener('click', () => { if (results.textContent && results.textContent !== '请输入关键词' && !results.textContent.includes('未找到')) { GM_setClipboard(results.textContent); const originalText = copyBtn.textContent; copyBtn.textContent = '已复制!'; setTimeout(() => { copyBtn.textContent = originalText; }, 2000); } }); // 初始状态 container.classList.add('expanded'); toggle.textContent = '▲'; toggle.style.transform = 'rotate(180deg)'; input.focus(); })();