XPath工具

按Shift+X在鼠标位置显示输入框,并提供实时反馈和高级配置选项操作XPath元素

目前為 2024-12-17 提交的版本,檢視 最新版本

// ==UserScript==
// @name         XPath工具
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  按Shift+X在鼠标位置显示输入框,并提供实时反馈和高级配置选项操作XPath元素
// @author       Ace
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    let toolbar = null;

    const SHOW_KEY = 'KeyX';

    function createToolbar() {
        if (document.getElementById('custom-toolbar')) return;

        toolbar = document.createElement('div');
        toolbar.id = 'custom-toolbar';
        toolbar.style.position = 'fixed';
        toolbar.style.zIndex = '9999';
        toolbar.style.backgroundColor = 'rgba(33, 33, 33, 0.95)';
        toolbar.style.color = '#fff';
        toolbar.style.padding = '15px';
        toolbar.style.borderRadius = '8px';
        toolbar.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
        toolbar.style.display = 'none';

        const input = document.createElement('input');
        input.id = 'custom-xpath-input';
        input.type = 'text';
        input.placeholder = '输入XPath';
        input.style.width = '250px';
        input.style.padding = '8px';
        input.style.border = '1px solid #ccc';
        input.style.borderRadius = '4px';
        toolbar.appendChild(input);

        const button = document.createElement('button');
        button.innerText = '删除';
        button.style.marginLeft = '10px';
        button.style.padding = '8px 12px';
        button.style.backgroundColor = '#e74c3c';
        button.style.color = '#fff';
        button.style.border = 'none';
        button.style.borderRadius = '4px';
        button.style.cursor = 'pointer';
        button.style.transition = 'background-color 0.3s';
        button.onmouseover = function () {
            button.style.backgroundColor = '#c0392b';
        };
        button.onmouseout = function () {
            button.style.backgroundColor = '#e74c3c';
        };
        button.onclick = function () {
            const userXPath = input.value;
            if (!userXPath) {
                alert('请输入XPath');
                return;
            }

            document.querySelectorAll('.highlighted-element').forEach((el) => {
                el.style.outline = '';
                el.classList.remove('highlighted-element');
            });

            const element = document.evaluate(
                userXPath,
                document,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
            ).singleNodeValue;

            if (element) {
                if (document.getElementById('style-checkbox').checked) {
                    element.style.display = 'none';
                    alert(`已隐藏元素: ${userXPath}`);
                } else {
                    element.remove();
                    alert(`已删除元素: ${userXPath}`);
                }
            } else {
                alert('未找到匹配的元素');
            }
        };
        toolbar.appendChild(button);

        const styleCheckbox = document.createElement('div');
        styleCheckbox.innerHTML = `
            <label style="display: flex; align-items: center; margin-top: 10px;">
                <input type="checkbox" id="style-checkbox" style="margin-right: 5px;"> 隐藏元素而不是删除
            </label>
        `;
        styleCheckbox.querySelector('input').addEventListener('change', (event) => {
            button.innerText = event.target.checked ? '隐藏' : '删除';
        });
        toolbar.appendChild(styleCheckbox);

        const highlightCheckbox = document.createElement('div');
        highlightCheckbox.innerHTML = `
            <label style="display: flex; align-items: center; margin-top: 5px;">
                <input type="checkbox" id="highlight-checkbox" style="margin-right: 5px;"> 高亮匹配的元素
            </label>
        `;
        toolbar.appendChild(highlightCheckbox);

        input.addEventListener('input', () => {
            if (document.getElementById('highlight-checkbox').checked) {
                highlightMatchingElements(input.value);
            }
        });

        highlightCheckbox.addEventListener('change', () => {
            const userXPath = input.value;
            if (highlightCheckbox.querySelector('input').checked && userXPath) {
                highlightMatchingElements(userXPath);
            } else {
                document.querySelectorAll('.highlighted-element').forEach((el) => {
                    el.style.outline = '';
                    el.classList.remove('highlighted-element');
                });
            }
        });

        document.body.appendChild(toolbar);
    }

    function highlightMatchingElements(userXPath) {
        document.querySelectorAll('.highlighted-element').forEach((el) => {
            el.style.outline = '';
            el.classList.remove('highlighted-element');
        });

        if (userXPath) {
            const element = document.evaluate(
                userXPath,
                document,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
            ).singleNodeValue;

            if (element) {
                element.style.outline = '2px solid red';
                element.classList.add('highlighted-element');
            }
        }
    }

    function toggleToolbarAtMouse(event) {
        if (!toolbar) return;

        const mouseX = event.clientX;
        const mouseY = event.clientY;

        toolbar.style.left = `${mouseX}px`;
        toolbar.style.top = `${mouseY}px`;

        toolbar.style.display = toolbar.style.display === 'none' ? 'block' : 'none';
    }

    createToolbar();

    document.addEventListener('keydown', (event) => {
        if (event.shiftKey && event.code === SHOW_KEY) {
            document.addEventListener('mousemove', (mouseEvent) => {
                toggleToolbarAtMouse(mouseEvent);
            }, { once: true });
        }
    });
})();

QingJ © 2025

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