Greasy Fork

Greasy Fork is available in English.

检查元素并复制

按下 Ctrl + Shift + Q 选择并复制元素文本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         检查元素并复制
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  按下 Ctrl + Shift + Q 选择并复制元素文本。
// @author       lsby
// @match        *://*/*
// @grant        GM_setClipboard
// @grant        GM_addStyle
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- 全局变量定义 ---
    let 选择模式激活 = false;
    let 当前高亮元素 = null;
    let 遮罩层 = null;
    let 信息标签 = null;

    // --- 初始化样式 ---
    GM_addStyle(`
        #元素选择遮罩 {
            pointer-events: none;
            position: fixed;
            z-index: 2147483647;
            background-color: rgba(0, 123, 255, 0.1);
            border: 2px solid rgba(0, 123, 255, 0.5);
            border-radius: 4px;
            transition: all 0.1s ease-out;
            display: none;
        }
        #元素选择标签 {
            position: absolute;
            top: -30px;
            left: 0;
            background: #007bff;
            color: white;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 12px;
            font-family: sans-serif;
            white-space: nowrap;
        }
        /* 统一弹窗样式 */
        .全局提示弹窗 {
            position: fixed;
            top: 24px;
            left: 50%;
            transform: translateX(-50%) translateY(-120%);
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(12px);
            padding: 14px 24px;
            border-radius: 12px;
            box-shadow: 0 12px 32px rgba(0,0,0,0.12);
            z-index: 2147483647;
            display: flex;
            flex-direction: column;
            gap: 4px;
            transition: all 0.4s cubic-bezier(0.19, 1, 0.22, 1);
            border-left: 6px solid #007bff;
            min-width: 280px;
        }
        .全局提示弹窗.显示 {
            transform: translateX(-50%) translateY(0);
        }
        .全局提示弹窗.成功 { border-left-color: #28a745; }
        .全局提示弹窗.提示 { border-left-color: #007bff; }

        .弹窗头部 {
            font-weight: 700;
            font-size: 15px;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .成功 .弹窗头部 { color: #28a745; }
        .提示 .弹窗头部 { color: #007bff; }

        .弹窗详细 {
            color: #555;
            font-size: 13px;
        }
        .选择模式鼠标 { cursor: crosshair !important; }
    `);

    // --- 通用通知函数 ---

    const 弹出通知 = (标题, 详细, 类型 = '提示') => {
        const 弹窗 = document.createElement('div');
        弹窗.className = `全局提示弹窗 ${类型}`;
        弹窗.innerHTML = `
            <div class="弹窗头部">${标题}</div>
            <div class="弹窗详细">${详细}</div>
        `;
        document.body.appendChild(弹窗);

        requestAnimationFrame(() => 弹窗.classList.add('显示'));

        setTimeout(() => {
            弹窗.classList.remove('显示');
            setTimeout(() => 弹窗.remove(), 400);
        }, 类型 === '提示' ? 2000 : 3000);
    };

    // --- 核心逻辑 ---

    const 创建UI组件 = () => {
        if (!遮罩层) {
            遮罩层 = document.createElement('div');
            遮罩层.id = '元素选择遮罩';
            信息标签 = document.createElement('div');
            信息标签.id = '元素选择标签';
            遮罩层.appendChild(信息标签);
            document.body.appendChild(遮罩层);
        }
    };

    const 更新高亮 = (目标) => {
        if (!目标 || 目标 === 遮罩层 || 目标 === document.body) return;
        const 矩形 = 目标.getBoundingClientRect();
        遮罩层.style.display = 'block';
        遮罩层.style.width = `${矩形.width}px`;
        遮罩层.style.height = `${矩形.height}px`;
        遮罩层.style.top = `${矩形.top}px`;
        遮罩层.style.left = `${矩形.left}px`;
        信息标签.textContent = `${目标.tagName.toLowerCase()}${目标.id ? '#'+目标.id : ''}`;
    };

    const 启动选择 = () => {
        选择模式激活 = true;
        创建UI组件();
        document.body.classList.add('选择模式鼠标');
        弹出通知('🔍 选择模式已开启', '请点击页面上的元素进行复制 (按 Esc 退出)');

        window.addEventListener('mousemove', 移动监听, true);
        window.addEventListener('click', 点击监听, true);
        window.addEventListener('keydown', 退出监听, true);
    };

    const 彻底关闭 = () => {
        选择模式激活 = false;
        if (遮罩层) 遮罩层.style.display = 'none';
        document.body.classList.remove('选择模式鼠标');
        window.removeEventListener('mousemove', 移动监听, true);
        window.removeEventListener('click', 点击监听, true);
        window.removeEventListener('keydown', 退出监听, true);
    };

    // --- 监听器 ---

    const 移动监听 = (e) => {
        if (!选择模式激活) return;
        if (e.target === 当前高亮元素) return;
        当前高亮元素 = e.target;
        更新高亮(e.target);
    };

    const 点击监听 = (e) => {
        if (!选择模式激活) return;
        e.preventDefault();
        e.stopPropagation();

        const 文本 = (当前高亮元素.innerText || 当前高亮元素.textContent || '').trim();
        if (文本) {
            GM_setClipboard(文本);
            弹出通知('✅ 复制成功', `内容:${文本.substring(0, 30)}${文本.length > 30 ? '...' : ''}`, '成功');
        }
        彻底关闭();
    };

    const 退出监听 = (e) => { e.key === 'Escape' && 彻底关闭(); };

    // 快捷键绑定
    window.addEventListener('keydown', (e) => {
        if (e.ctrlKey && e.shiftKey && e.key.toUpperCase() === 'Q') {
            选择模式激活 ? 彻底关闭() : 启动选择();
        }
    });

})();