Greasy Fork

通用自动点击脚本(定时版)

支持定时自动点击,并通过鼠标右键选择目标元素,自动生成 CSS 或 XPath 选择器。

目前为 2024-11-23 提交的版本。查看 最新版本

// ==UserScript==
// @name         通用自动点击脚本(定时版)
// @namespace    http://tampermonkey.net/
// @version      3.1
// @description  支持定时自动点击,并通过鼠标右键选择目标元素,自动生成 CSS 或 XPath 选择器。
// @author       Universal
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    const CONFIG = {
        CONTROL_PANEL_ID: 'autoClickControl', // 控制面板ID
        OVERLAY_ID: 'elementOverlay', // 高亮层ID
        CLICK_INTERVAL: 500, // 每次点击间隔 (毫秒)
        MAX_CLICKS: 20, // 最大点击次数
    };

    const State = {
        targetSelector: GM_getValue('targetSelector', ''), // 目标选择器
        isPicking: false, // 是否正在选择目标元素
        isRunning: false, // 是否正在运行点击
        timer: null, // 定时器
        clickCount: 0, // 当前点击次数
        executeTime: GM_getValue('executeTime', ''), // 定时执行时间
        debug: true, // 是否启用调试日志
    };

    // 调试日志
    function debugLog(...args) {
        if (State.debug) console.log('[Debug]', ...args);
    }

    // 添加样式
    function addStyles() {
        GM_addStyle(`
            #autoClickControl {
                position: fixed;
                top: 10px;
                right: 10px;
                z-index: 9999;
                background: #fff;
                border: 1px solid #ccc;
                padding: 15px;
                border-radius: 5px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                font-family: Arial, sans-serif;
                width: 300px;
            }
            #autoClickControl input, #autoClickControl button {
                margin-bottom: 10px;
            }
            #autoClickControl input {
                width: 100%;
                padding: 5px;
                border: 1px solid #ddd;
                border-radius: 3px;
            }
            #autoClickControl button {
                padding: 5px 10px;
                border: none;
                border-radius: 3px;
                cursor: pointer;
            }
            #autoClickControl #startButton {
                background-color: #28a745;
                color: white;
            }
            #autoClickControl #pickButton {
                background-color: #007bff;
                color: white;
            }
            #autoClickControl #stopButton {
                background-color: #dc3545;
                color: white;
            }
            #elementOverlay {
                position: absolute;
                border: 2px dashed #007bff;
                background-color: rgba(0, 123, 255, 0.2);
                pointer-events: none;
                z-index: 9998;
                display: none;
            }
        `);
    }

    // 创建控制面板
    function createControlPanel() {
        if (document.getElementById(CONFIG.CONTROL_PANEL_ID)) return;

        const controlPanel = document.createElement('div');
        controlPanel.id = CONFIG.CONTROL_PANEL_ID;
        controlPanel.innerHTML = `
            <label>目标选择器 (CSS选择器或XPath):</label>
            <input type="text" id="targetSelectorInput" placeholder="通过右键选择或手动输入" value="${State.targetSelector}">
            <label>执行时间:</label>
            <input type="datetime-local" id="executeTimeInput" value="${State.executeTime}">
            <button id="pickButton">右键选择目标</button>
            <button id="startButton">开始</button>
            <button id="stopButton" disabled>停止</button>
            <div id="statusText">状态: 未运行</div>
        `;
        document.body.appendChild(controlPanel);

        // 绑定事件
        document.getElementById('pickButton').addEventListener('click', enableElementPicker);
        document.getElementById('startButton').addEventListener('click', startClicking);
        document.getElementById('stopButton').addEventListener('click', stopClicking);
        document.getElementById('targetSelectorInput').addEventListener('input', (event) => {
            State.targetSelector = event.target.value.trim();
            GM_setValue('targetSelector', State.targetSelector);
        });
        document.getElementById('executeTimeInput').addEventListener('change', (event) => {
            State.executeTime = event.target.value.trim();
            GM_setValue('executeTime', State.executeTime);
        });
    }

    // 更新状态文本
    function updateStatus(message) {
        document.getElementById('statusText').innerText = `状态: ${message}`;
    }

    // 启用目标选择
    function enableElementPicker() {
        alert('请右键单击页面上的目标元素来选择它。');
        State.isPicking = true;

        document.addEventListener('mouseover', highlightElement, true);
        document.addEventListener('contextmenu', selectElement, true);
    }

    // 停用目标选择
    function disableElementPicker() {
        State.isPicking = false;
        const overlay = document.getElementById(CONFIG.OVERLAY_ID);
        overlay.style.display = 'none';

        document.removeEventListener('mouseover', highlightElement, true);
        document.removeEventListener('contextmenu', selectElement, true);
    }

    // 高亮鼠标悬停的元素
    function highlightElement(event) {
        if (!State.isPicking) return;

        const overlay = document.getElementById(CONFIG.OVERLAY_ID);
        const target = event.target;

        if (!target) return;
        const rect = target.getBoundingClientRect();
        overlay.style.display = 'block';
        overlay.style.top = `${rect.top + window.scrollY}px`;
        overlay.style.left = `${rect.left + window.scrollX}px`;
        overlay.style.width = `${rect.width}px`;
        overlay.style.height = `${rect.height}px`;
        debugLog('Highlighting element:', target);
    }

    // 选择目标元素
    function selectElement(event) {
        if (!State.isPicking) return;

        event.preventDefault();
        const target = event.target;

        const selector = generateSelector(target);
        State.targetSelector = selector;
        GM_setValue('targetSelector', selector);

        document.getElementById('targetSelectorInput').value = selector;
        disableElementPicker();
        alert(`目标元素已选择: ${selector}`);
        debugLog('Selected element:', target, 'Generated selector:', selector);
    }

    // 自动生成 CSS 选择器
    function generateSelector(element) {
        if (!element) return null;

        let selector = element.tagName.toLowerCase();
        if (element.id) {
            selector += `#${element.id}`;
        } else if (element.className) {
            const className = element.className.trim().split(/\s+/).join('.');
            selector += `.${className}`;
        }
        return selector;
    }

    // 定时点击功能(省略重复代码)...
    // 创建高亮层
    function createOverlay() {
        if (document.getElementById(CONFIG.OVERLAY_ID)) return;

        const overlay = document.createElement('div');
        overlay.id = CONFIG.OVERLAY_ID;
        document.body.appendChild(overlay);
    }

    function initialize() {
        addStyles();
        createControlPanel();
        createOverlay();
    }

    initialize();
})();