元素关键字查找工具

查找当前页面全部元素中的关键字

当前为 2025-07-01 提交的版本,查看 最新版本

// ==UserScript==
// @name        元素关键字查找工具
// @namespace   http://tampermonkey.net/
// @version     0.3
// @description 查找当前页面全部元素中的关键字
// @author      八千xmx
// @match       *://*/*
// @grant       GM_setClipboard
// @grant       GM_addStyle
// @license GNU GPLv3
// ==/UserScript==

(function() {
    'use strict';

    // 添加全局样式
    GM_addStyle(`
        .dedupe-search-container {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 320px;
            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);
        }

        .dedupe-search-container.expanded {
            max-height: 350px;
        }

        .dedupe-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);
        }

        .dedupe-search-content {
            padding: 12px;
            overflow-y: auto;
            max-height: 280px;
        }

        .dedupe-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);
        }

        .dedupe-search-results {
            font-size: 13px;
            line-height: 1.5;
            white-space: pre-wrap;
            max-height: 200px;
            overflow-y: auto;
            padding: 5px 0;
        }

        .dedupe-search-match {
            background: rgba(255, 235, 59, 0.35);
            padding: 0 2px;
            border-radius: 2px;
            margin: 2px 0;
        }

        .dedupe-search-buttons {
            display: flex;
            gap: 8px;
            margin-top: 10px;
        }

        .dedupe-search-button {
            flex: 1;
            padding: 8px;
            border: none;
            border-radius: 4px;
            font-size: 13px;
            cursor: pointer;
            transition: all 0.2s;
        }

        .dedupe-search-button.search {
            background: #4CAF50;
            color: white;
        }

        .dedupe-search-button.copy {
            background: #2196F3;
            color: white;
        }

        .dedupe-search-count {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
            text-align: right;
        }

        .dedupe-search-toggle {
            transition: transform 0.2s;
        }
    `);

    // 创建容器
    const container = document.createElement('div');
    container.className = 'dedupe-search-container';
    container.innerHTML = `
        <div class="dedupe-search-header">
            <span>🔍 关键字查找(去重)</span>
            <span class="dedupe-search-toggle">▼</span>
        </div>
        <div class="dedupe-search-content">
            <input type="text" class="dedupe-search-input" placeholder="输入关键字...">
            <div class="dedupe-search-buttons">
                <button class="dedupe-search-button search">查找</button>
                <button class="dedupe-search-button copy">复制</button>
            </div>
            <div class="dedupe-search-results"></div>
            <div class="dedupe-search-count"></div>
        </div>
    `;

    document.body.appendChild(container);

    const header = container.querySelector('.dedupe-search-header');
    const content = container.querySelector('.dedupe-search-content');
    const input = container.querySelector('.dedupe-search-input');
    const searchBtn = container.querySelector('.dedupe-search-button.search');
    const copyBtn = container.querySelector('.dedupe-search-button.copy');
    const results = container.querySelector('.dedupe-search-results');
    const countDisplay = container.querySelector('.dedupe-search-count');
    const toggle = container.querySelector('.dedupe-search-toggle');

    // 查找当前元素内容并去重
    function searchAndDeduplicate(keyword) {
        if (!keyword) {
            results.innerHTML = '<div style="color:#666">请输入关键字</div>';
            countDisplay.textContent = '';
            return;
        }

        const selection = window.getSelection();
        let currentElement = selection.anchorNode;

        // 如果没有选中内容,使用整个body
        if (!currentElement || currentElement.nodeType !== Node.TEXT_NODE) {
            currentElement = document.body;
        } else {
            currentElement = currentElement.parentElement;
        }

        const text = currentElement.textContent.trim();
        const regex = new RegExp(`(${escapeRegExp(keyword)})`, 'gi');

        if (text && regex.test(text)) {
            // 获取所有匹配的行
            const lines = text.split('\n')
                .map(line => line.trim())
                .filter(line => line.length > 0 && regex.test(line));

            // 去重处理
            const uniqueLines = [...new Set(lines)];

            // 高亮显示
            const highlighted = uniqueLines.map(line =>
                line.replace(regex, '<span class="dedupe-search-match">$1</span>')
            ).join('<br>');

            results.innerHTML = highlighted;
            countDisplay.textContent = `找到 ${uniqueLines.length} 个唯一结果 (原始 ${lines.length} 个)`;
        } 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', () => {
        searchAndDeduplicate(input.value.trim());
    });

    input.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            searchAndDeduplicate(input.value.trim());
        }
    });

    copyBtn.addEventListener('click', () => {
        if (results.textContent) {
            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();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址