// ==UserScript== // @name 搜索Tool // @version 0.6.2 // @description 搜索引擎快速切换工具 // @author lawchou // @include http*://*.bing.com/* // @include http*://*.google.com/* // @include http*://*.baidu.com/* // @include http*://*.sogou.com/* // @include http*://*.sogou.cn/* // @include http*://*.haoso.com/* // @include http*://*.so.com/* // @include http*://*.yandex.com/* // @include http*://*.metaso.cn/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function () { 'use strict'; /* ---------- 默认 4 个引擎 ---------- */ const DEFAULT_ENGINES = [ { id: 'baidu', name: '百度', url: 'https://www.baidu.com/s?wd=%s', color: '#2932e1' }, { id: 'bing', name: '必应', url: 'https://cn.bing.com/search?q=%s', color: '#0078d4' }, { id: 'google', name: 'Google', url: 'https://www.google.com/search?q=%s', color: '#4285f4' }, { id: 'so', name: '360', url: 'https://www.so.com/s?q=%s', color: '#19b955' } ]; const STORAGE_KEY = 'sp_engines'; /* ---------- 工具 ---------- */ function loadEngines() { try { return JSON.parse(GM_getValue(STORAGE_KEY, '[]')) || DEFAULT_ENGINES; } catch { return DEFAULT_ENGINES; } } function saveEngines(list) { GM_setValue(STORAGE_KEY, JSON.stringify(list)); } function isSearchPage() { const p = new URLSearchParams(location.search); return !!(p.get('q') || p.get('wd') || p.get('s')); } function getKeyword() { const p = new URLSearchParams(location.search); return p.get('wd') || p.get('q') || p.get('s') || ''; } function currentEngineId() { const host = location.hostname.replace(/^www\./, ''); if (host.includes('baidu')) return 'baidu'; if (host.includes('bing')) return 'bing'; if (host.includes('google'))return 'google'; if (host.includes('so.com') || host.includes('haoso')) return 'so'; return null; } /* ---------- 样式(无背景图标) ---------- */ GM_addStyle(` #sp-ac-container{position:fixed;right:55px;top:68%;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;} #sp-toggle-btn{width:42px;height:42px;border-radius:50%;background:#34c0f1;border:none;color:#fff;font-size:18px;cursor:pointer;box-shadow:0 4px 10px rgba(0,0,0,.25);transition:transform .2s;} #sp-toggle-btn:hover{transform:scale(1.1);} #sp-toggle-btn.active{background:#ff6b35;} #sp-engine-list{ position:absolute;bottom:60px;right:0; display:flex;flex-direction:column;gap:18px; opacity:0;pointer-events:none;transform:translateY(10px); transition:opacity .25s,transform .25s; } #sp-settings-btn{ position:absolute;top:60px;right:0; width:42px;height:42px;border-radius:50%;border:none;background:#888;color:#fff;font-size:16px;cursor:pointer; opacity:0;pointer-events:none;transform:translateY(-10px); transition:opacity .25s,transform .25s; } .show{opacity:1!important;pointer-events:auto!important;transform:none!important;} /* 28×28 透明 favicon,无边框无背景 */ .sp-engine-btn{ width:42px;height:42px;border-radius:50%;border:none; background-color:transparent; /* 去掉背景色 */ background-size:28px 28px; /* 放大图标 */ background-repeat:no-repeat; background-position:center; cursor:pointer; transition:transform .2s; } .sp-engine-btn:hover{transform:translateX(-5px);} #sp-settings{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:340px;background:#fff;border-radius:8px;box-shadow:0 8px 30px rgba(0,0,0,.3);padding:20px;z-index:1000000;font-size:14px;} #sp-settings h3{margin:0 0 10px;} #sp-settings input{width:calc(100% - 8px);margin:4px 0 8px;padding:4px;border:1px solid #ccc;border-radius:4px;} #sp-settings .item{display:flex;justify-content:space-between;align-items:center;margin:4px 0;} #sp-settings .item span{flex:1;} #sp-settings .item button{background:#ff4d4f;color:#fff;border:none;border-radius:4px;padding:2px 6px;cursor:pointer;} #sp-settings .add-btn{background:#52c41a;color:#fff;border:none;border-radius:4px;padding:4px 8px;margin-top:8px;cursor:pointer;} #sp-settings .close-btn{position:absolute;top:8px;right:8px;background:transparent;border:none;font-size:18px;cursor:pointer;color:#666;} `); /* ---------- 主逻辑 ---------- */ let hideTimer = null; let engines = loadEngines(); if(JSON.stringify(engines) === '[]') { engines=DEFAULT_ENGINES } function MAIN() { if (!isSearchPage()) return; createPanel(); } function createPanel() { const box = document.createElement('div'); box.id = 'sp-ac-container'; box.innerHTML = `
`; document.body.appendChild(box); const toggleBtn = document.getElementById('sp-toggle-btn'); const engineList = document.getElementById('sp-engine-list'); const settingsBtn = document.getElementById('sp-settings-btn'); toggleBtn.addEventListener('click', () => { const expanded = toggleBtn.classList.toggle('active'); engineList.classList.toggle('show', expanded); settingsBtn.classList.toggle('show', expanded); clearTimeout(hideTimer); }); box.addEventListener('mouseleave', () => { hideTimer = setTimeout(() => { toggleBtn.classList.remove('active'); engineList.classList.remove('show'); settingsBtn.classList.remove('show'); }, 2000); }); box.addEventListener('mouseenter', () => clearTimeout(hideTimer)); box.addEventListener('click', e => { const id = e.target.dataset.engine; if (id) { const obj = engines.find(v => v.id === id); if (obj) { const kw = encodeURIComponent(getKeyword()); window.open(obj.url.replace('%s', kw), '_blank'); } } }); settingsBtn.addEventListener('click', openSettings); renderEngines(); } function renderEngines() { const list = document.getElementById('sp-engine-list'); list.innerHTML = ''; const currentId = currentEngineId(); engines .filter(e => e.id !== currentId) .slice(0, 4) .forEach(e => { const btn = document.createElement('button'); btn.className = 'sp-engine-btn'; btn.style.backgroundImage = `url(https://ico.scdn.io/api/api/favicon.php?url=${new URL(e.url).hostname})`; btn.dataset.engine = e.id; btn.title = e.name; list.appendChild(btn); }); } function openSettings() { if (document.getElementById('sp-settings')) return; const panel = document.createElement('div'); panel.id = 'sp-settings'; panel.innerHTML = `