Greasy Fork

Greasy Fork is available in English.

聚合搜索

整合网页搜索,优化UI,深色模式支持, 在 http://greasyfork.icu/zh-CN/scripts/436613-%E8%81%9A%E5%90%88%E6%90%9C%E7%B4%A2/ 的基础上改进

// ==UserScript==
// @name         聚合搜索
// @namespace    http://tampermonkey.net/
// @version      0.2.0
// @description  整合网页搜索,优化UI,深色模式支持, 在 http://greasyfork.icu/zh-CN/scripts/436613-%E8%81%9A%E5%90%88%E6%90%9C%E7%B4%A2/ 的基础上改进
// @author       Peng Shiyu, 海洋空氣, xubairr
// @match        *://www.baidu.com/s*
// @match        *://*.bing.com/search*
// @match        *://www.google.com.hk/search*
// @match        *://www.google.com/search*
// @match        *://metaso.cn/search*
// @match        *://duckduckgo.com/?q*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // 搜索网址配置
    const urlMapping = [
        { name: '百度', searchUrl: 'https://www.baidu.com/s?wd=', keyName: 'wd', testUrl: /https:\/\/www\.baidu\.com\/s.*/ },
        { name: '必应国内版', searchUrl: 'https://www.bing.com/search?ensearch=0&q=', keyName: 'q', testUrl: /https:\/\/www\.bing\.com\/search.*/ },
        { name: '必应国际版', searchUrl: 'https://www.bing.com/search?ensearch=1&q=', keyName: 'q', testUrl: /https:\/\/www\.bing\.com\/search.*/ },
        { name: 'Google', searchUrl: 'https://www.google.com/search?q=', keyName: 'q', testUrl: /https:\/\/www\.google\.com\/search.*/ },
        { name: 'Google.hk', searchUrl: 'https://www.google.com.hk/search?q=', keyName: 'q', testUrl: /https:\/\/www\.google\.com\.hk\/search.*/ },
        { name: '秘塔AI', searchUrl: 'https://metaso.cn?q=', keyName: 'q', testUrl: /https:\/\/metaso\.cn\/.*/ },
        { name: 'DuckDuckGo', searchUrl: 'https://duckduckgo.com/?q=', keyName: 'q', testUrl: /https:\/\/duckduckgo\.com\/.*(\?q=.*)?/ }
    ];

    // 获取 URL 参数
    function getQueryVariable(variable) {
        const query = window.location.search.substring(1);
        const pairs = query.split("&");
        for (let pair of pairs) {
            const [key, value] = pair.split("=");
            if (key === variable) {
                return decodeURIComponent(value);
            }
        }
        return null;
    }

    // 获取当前关键词
    function getKeywords() {
        for (let item of urlMapping) {
            if (item.testUrl.test(window.location.href)) {
                return getQueryVariable(item.keyName);
            }
        }
        return '';
    }

    // 判断是否为深色模式
    function isDarkMode() {
        return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
    }

    // 添加 UI 元素
    function addBox() {
        // 删除旧的
        const oldBox = document.getElementById('search-app-box');
        if (oldBox) oldBox.remove();

        const keywords = getKeywords();
        const darkMode = isDarkMode();

        // 创建主容器
        const div = document.createElement('div');
        div.id = 'search-app-box';
        div.style.cssText = `
            position: fixed;
            top: 160px;
            left: 20px;
            width: 120px;
            background-color: ${darkMode ? '#2d2d2d' : '#ffffff'};
            color: ${darkMode ? '#f0f0f0' : '#333333'};
            font-size: 13px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
            z-index: 99999;
            padding: 10px 0;
            transition: background-color 0.3s ease, color 0.3s ease;
        `;
        document.body.insertAdjacentElement("afterBegin", div);

        // 标题
        const title = document.createElement('div');
        title.innerText = "🔍 聚合搜索";
        title.style.cssText = `
            text-align: center;
            font-weight: bold;
            margin-bottom: 8px;
            font-size: 14px;
        `;
        div.appendChild(title);

        // 搜索链接
        urlMapping.forEach((item, index) => {
            const a = document.createElement('a');
            a.href = item.searchUrl + encodeURIComponent(keywords);
            a.target = '_self';
            a.innerText = item.name;
            a.style.cssText = `
                display: block;
                padding: 8px 12px;
                text-decoration: none;
                color: inherit;
                transition: background-color 0.2s ease;
                border-radius: 4px;
                margin: 0 6px;
                cursor: pointer;
            `;

            // 点击事件:在当前页面跳转
            a.addEventListener('click', function(e) {
                e.preventDefault();
                window.location.href = item.searchUrl + encodeURIComponent(keywords);
            });

            a.onmouseenter = () => {
                a.style.backgroundColor = darkMode ? '#444' : '#eaeaea';
            };
            a.onmouseleave = () => {
                a.style.backgroundColor = 'transparent';
            };
            div.appendChild(a);
        });
    }

    // 页面变化监听
    if (window.onurlchange === null) {
        window.addEventListener('urlchange', addBox);
    }

    // 初始化
    window.addEventListener('load', addBox);
})();