Greasy Fork

Greasy Fork is available in English.

拖拽搜索

通过拖拽文本实现快速搜索

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         拖拽搜索
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  通过拖拽文本实现快速搜索
// @author       PaulW47
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 默认搜索引擎配置
    const defaultEngines = {
        up: {
            name: '百度',
            url: 'https://www.baidu.com/s?wd='
        },
        right: {
            name: '谷歌',
            url: 'https://www.google.com/search?q='
        },
        down: {
            name: '必应',
            url: 'https://www.bing.com/search?q='
        },
        left: {
            name: '必应',
            url: 'https://www.bing.com/search?q='
        }
    };

    // 添加预定义的搜索引擎列表
    const defaultEnginesList = {
        'baidu': {
            name: '百度',
            url: 'https://www.baidu.com/s?wd='
        },
        'google': {
            name: '谷歌',
            url: 'https://www.google.com/search?q='
        },
        'bing': {
            name: '必应',
            url: 'https://www.bing.com/search?q='
        }
    };

    // 获取保存的搜索引擎配置和列表
    let searchEngines = GM_getValue('searchEngines', defaultEngines);
    let enginesList = GM_getValue('enginesList', defaultEnginesList);

    let dragIndicator = null;

    function createDragIndicator() {
        const indicator = document.createElement('div');
        indicator.style.cssText = `
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 16px;
            z-index: 10000;
            display: none;
        `;
        document.body.appendChild(indicator);
        return indicator;
    }

    // 创建设置面板
    function createSettingsPanel() {
        const panel = document.createElement('div');
        panel.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.5);
            z-index: 10000;
            max-width: 600px;
            width: 90%;
        `;

        // 创建搜索引擎管理部分的HTML
        const enginesListHTML = `
            <div style="margin-bottom: 20px; border-bottom: 1px solid #ccc; padding-bottom: 15px;">
                <h3>添加新的搜索引擎</h3>
                <div style="margin: 10px 0;">
                    <input type="text" id="new-engine-name" placeholder="搜索引擎名称" style="margin-right: 5px;">
                    <input type="text" id="new-engine-url" placeholder="搜索URL" style="width: 250px; margin-right: 5px;">
                    <button id="add-engine">添加</button>
                </div>
            </div>
        `;

        // 创建方向设置部分的HTML
        const directionsHTML = Object.entries(searchEngines).map(([direction, engine]) => `
            <div style="margin: 10px 0;">
                <label>${direction === 'up' ? '向上' : direction === 'right' ? '向右' :
                       direction === 'down' ? '向下' : '向左'}方向:</label>
                <select id="select-${direction}" style="margin: 0 5px; width: 150px;">
                    ${Object.entries(enginesList).map(([key, e]) => `
                        <option value="${key}" ${e.name === engine.name ? 'selected' : ''}>
                            ${e.name}
                        </option>
                    `).join('')}
                </select>
            </div>
        `).join('');

        panel.innerHTML = `
            <h2 style="margin-top: 0;">搜索引擎设置</h2>
            ${enginesListHTML}
            <h3>方向设置</h3>
            ${directionsHTML}
            <div style="margin-top: 15px;">
                <button id="save-settings">保存</button>
                <button id="close-settings">关闭</button>
            </div>
        `;

        document.body.appendChild(panel);

        // 添加新搜索引擎的处理
        document.getElementById('add-engine').onclick = () => {
            const name = document.getElementById('new-engine-name').value.trim();
            const url = document.getElementById('new-engine-url').value.trim();

            if (name && url) {
                const key = name.toLowerCase().replace(/\s+/g, '_');
                enginesList[key] = { name, url };
                GM_setValue('enginesList', enginesList);
                // 刷新设置面板
                panel.remove();
                createSettingsPanel();
            }
        };

        // 保存设置
        document.getElementById('save-settings').onclick = () => {
            Object.keys(searchEngines).forEach(direction => {
                const selectedKey = document.getElementById(`select-${direction}`).value;
                searchEngines[direction] = enginesList[selectedKey];
            });
            GM_setValue('searchEngines', searchEngines);
            panel.remove();
        };

        document.getElementById('close-settings').onclick = () => panel.remove();
    }

    // 注册设置菜单
    GM_registerMenuCommand('设置搜索引擎', createSettingsPanel);

    // 处理拖拽
    let startX, startY;
    let selectedText = '';

    document.addEventListener('dragstart', (e) => {
        startX = e.clientX;
        startY = e.clientY;
        selectedText = window.getSelection().toString().trim();

        // 创建提示元素
        if (!dragIndicator) {
            dragIndicator = createDragIndicator();
        }
    });

    document.addEventListener('drag', (e) => {
        if (!selectedText || !e.clientX || !e.clientY) return; // 某些浏览器可能返回0

        const deltaX = e.clientX - startX;
        const deltaY = e.clientY - startY;
        const absX = Math.abs(deltaX);
        const absY = Math.abs(deltaY);

        let direction;
        if (absX > absY) {
            direction = deltaX > 0 ? 'right' : 'left';
        } else {
            direction = deltaY > 0 ? 'down' : 'up';
        }

        const engine = searchEngines[direction];
        if (engine) {
            dragIndicator.textContent = `${engine.name}搜索`;
            dragIndicator.style.display = 'block';
        }
    });

    document.addEventListener('dragend', (e) => {
        // 隐藏提示元素
        if (dragIndicator) {
            dragIndicator.style.display = 'none';
        }

        if (!selectedText) return;

        const deltaX = e.clientX - startX;
        const deltaY = e.clientY - startY;
        const absX = Math.abs(deltaX);
        const absY = Math.abs(deltaY);

        let direction;
        if (absX > absY) {
            direction = deltaX > 0 ? 'right' : 'left';
        } else {
            direction = deltaY > 0 ? 'down' : 'up';
        }

        const engine = searchEngines[direction];
        if (engine) {
            const searchUrl = engine.url + encodeURIComponent(selectedText);
            window.open(searchUrl, '_blank');
        }
    });
})();