搜索引擎切换[PC+移动端]

快速切换搜索引擎,自动提取搜索关键词,一键跳转,自动隐藏、自动显示。目前支持谷歌、百度、Yandex、B站、知乎等十几种搜索。区分了PC端和移动端的显示样式

目前为 2025-02-14 提交的版本。查看 最新版本

// ==UserScript==
// @name         搜索引擎切换[PC+移动端]
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  快速切换搜索引擎,自动提取搜索关键词,一键跳转,自动隐藏、自动显示。目前支持谷歌、百度、Yandex、B站、知乎等十几种搜索。区分了PC端和移动端的显示样式
// @author       DQIT
// @match        *://www.google.com*/search*
// @match        *://www.google.com.hk*/search*
// @match        *://www.bing.com/search*
// @match        *://cn.bing.com/search*
// @match        *://www.baidu.com/s*
// @match        *://www.baidu.com/baidu*
// @match        *://chatgpt.com/*
// @match        *://metaso.cn/*
// @match        *://weixin.sogou.com/weixin*
// @match        *://search.bilibili.com/all*
// @match        *://www.youtube.com/results*
// @match        *://m.youtube.com/results*
// @match        *://www.zhihu.com/search*
// @match        *://github.com/search*
// @match        *://www.xiaohongshu.com/explore*
// @match        *://www.douyin.com/search/*
// @match        *://yandex.com/*
// @match        *://duckduckgo.com/*
// @match        *://www.perplexity.ai/*
// @grant        GM_addElement
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 搜索引擎列表
    const engins = [
        { name: "Google", searchUrl: "https://www.google.com/search?q=", keyName: "q", testUrl: /https:\/\/www\.google\.(com|com\.hk)\/search.*/ },
        { name: "Bing", searchUrl: "https://www.bing.com/search?q=", keyName: "q", testUrl: /https:\/\/(www|cn)\.bing\.com\/search.*/ },
        { name: "百度", searchUrl: "https://www.baidu.com/s?wd=", keyName: "wd", testUrl: /https:\/\/www\.baidu\.com\/(s|baidu).*/ },
        { name: "Yandex", searchUrl: "https://yandex.com/search/?text=", keyName: "text", testUrl: /https:\/\/(www|cn)\.yandex\.com\/search.*/ },
        { name: "DuckDuckGo", searchUrl: "https://duckduckgo.com/?q=", keyName: "q", testUrl: /https:\/\/duckduckgo\.cn\/.*/ },
        { name: "ChatGPT", searchUrl: "https://chatgpt.com/?hints=search&q=", keyName: "q", testUrl: /https:\/\/chatgpt\.com\/.*/ },
        { name: "秘塔", searchUrl: "https://metaso.cn/?q=", keyName: "q", testUrl: /https:\/\/metaso\.cn\/.*/ },
        { name: "Youtube", searchUrl: "https://www.youtube.com/results?search_query=", keyName: "search_query", testUrl: /https:\/\/(www|m)\.youtube\.com\/results.*/ },
        { name: "GitHub", searchUrl: "https://github.com/search?q=", keyName: "q", testUrl: /https:\/\/github\.com\/search.*/ },
        { name: "知乎", searchUrl: "https://www.zhihu.com/search?q=", keyName: "q", testUrl: /https:\/\/www\.zhihu\.com\/search.*/ },
        { name: "B站", searchUrl: "https://search.bilibili.com/all?keyword=", keyName: "keyword", testUrl: /https:\/\/search\.bilibili\.com\/all.*/ },
        { name: "微信", searchUrl: "https://weixin.sogou.com/weixin?type=2&s_from=input&query=", keyName: "query", testUrl: /https:\/\/weixin\.sogou\.com\/weixin.*/ },
        { name: "小红书", searchUrl: "https://www.xiaohongshu.com/explore?q=", keyName: "q", testUrl: /https:\/\/www\.xiaohongshu\.com\/explore.*/ },
        { name: "抖音", searchUrl: "https://www.douyin.com/search/", keyName: "q", testUrl: /https:\/\/www\.douyin\.com\/search\/.*/ },
        { name: "Perplexity", searchUrl: "https://www.perplexity.ai/?q=", keyName: "q", testUrl: /https:\/\/www\.perplexity\.ai\/.*/ },
    ];

    // 获取当前搜索关键词
    function getKeywords() {
        for (const item of engins) {
            if (item.testUrl.test(window.location.href)) {
                var keyName = item.keyName;
                const query = window.location.search.substring(1);
                const vars = query.split('&');
                for (let i = 0; i < vars.length; i++) {
                    const pair = vars[i].split('=');
                    if (decodeURIComponent(pair[0]) === keyName) {
                        return decodeURIComponent(pair[1]);
                    }
                }
                if (keyName === "q" && window.location.pathname.startsWith("/search/")) {
                    return decodeURIComponent(window.location.pathname.replace("/search/", ""));
                }
                return "";
            }
        }
        return "";
    }

    // 创建移动端按钮
    function createMobileButtons(keyword) {
        //创建按钮容器
        const container = document.createElement('div');
        container.style.cssText = `
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            background: linear-gradient(135deg, rgb(212, 227, 252, 0.4), rgb(240, 239, 253, 0.4));
            backdrop-filter: blur(10px);
            padding: 12px 8px;
            z-index: 9999;
            box-shadow: 0 -4px 20px rgba(0,0,0,0.1);
            display: flex;
            overflow-x: auto;
            gap: 8px;
            border-top: 1px solid rgba(255,255,255,0.2);
        `;

        //创建按钮
        for (const engine of engins) {
            if(engine.testUrl.test(window.location.href)){
                continue;
            }
            const btn = document.createElement('a');
            btn.href = engine.searchUrl + encodeURIComponent(keyword);
            btn.target = '_blank';
            btn.style.cssText = `
                display: inline-flex;
                padding: 8px 16px;
                background: rgba(255,255,255,0.7);
                backdrop-filter: blur(4px);
                color: #2c3e50!important;
                border-radius: 24px;
                text-decoration: none;
                font-size: 14px;
                flex-shrink: 0;
                border: 1px solid rgba(0,0,0,0.1);
                transition: all 0.2s;
                font-weight: 500;
                box-shadow: 0 2px 6px rgba(0,0,0,0.05);
            `;
            btn.innerHTML = engine.name;
            container.appendChild(btn);
        }

        document.body.appendChild(container);

        let lastScrollTop = 0;
        window.addEventListener('scroll', function() {
            const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
            if (scrollTop > lastScrollTop) {
                // 向下滚动,隐藏横条
                container.style.display = 'none';
            } else {
                // 向上滚动,显示横条
                container.style.display = 'inline-flex';
            }

            lastScrollTop = scrollTop;
        });

    }

    // 创建PC端按钮
    function createPCButtons(keyword){
        //创建容器
        const container = document.createElement('div');
        container.style.cssText = `
            position: fixed;
            width: 112px;
            top: 150px;
            left: 10px;
            background: linear-gradient(135deg, rgb(212, 227, 252, 0.8), rgb(240, 239, 253, 0.8));
            backdrop-filter: blur(10px);
            box-shadow: 1px 1px 1px rgba(0,0,0,0.1);
            z-index: 9999;
            border-radius: 10px;
            transition: all 0.3s;
        `;
        //动态高度, 避免增加或移除搜索引擎时要重新计算高度
        container.style.height = 45 * engins.length + 12 + 'px';
        //创建按钮
        for (const engine of engins) {
            if(engine.testUrl.test(window.location.href)){
                continue;
            }
            const btn = document.createElement('div');
            btn.style.cssText = `
                align-items: center;
                margin-top: 10px;
                margin-left: 6px;
                width: 100px;
                height: 35px;
                background-color: rgba(255,255,255,0.8);
                border-radius: 15px;
                display: flex;
                justify-content: center;
                transition: all 0.5s;
            `;
            btn.textContent = engine.name;
            // 悬停效果
            btn.addEventListener('mouseover', () => {
                btn.style.background = 'rgba(255,255,255,1)';
                btn.style.transform = 'translateY(-3px)';
            });
            btn.addEventListener('mouseout', () => {
                btn.style.background = 'rgba(255,255,255,0.8)';
                btn.style.transform = 'none';
            });

            // 绑定点击跳转事件
            btn.addEventListener('click', function() {
                window.open(engine.searchUrl + encodeURIComponent(keyword),'_self')
            });

            container.appendChild(btn);
        }

        //显示容器
        document.body.prepend(container);

        let lastScrollTop = 0;
        window.addEventListener('scroll', function() {
            const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

            if (scrollTop > lastScrollTop) {
                // 向下滚动,隐藏侧栏
                container.style.left = '-122px';
            } else {
                // 向上滚动,显示侧栏
                container.style.left = '10px';
            }

            lastScrollTop = scrollTop;
        });

    }


    // 执行逻辑优化
    setTimeout(() => {
        //是否是移动端
        const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
        let keyword = getKeywords();
        if(!keyword){
            //未提取到关键词不显示
            return;
        }else {
            if(isMobile){
                //显示移动端
                createMobileButtons(keyword);
            }else {
                //显示PC端
                createPCButtons(keyword);
            }
        }
    }, 500);
})();