您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在任意页面右侧浮动一个快捷脚本启动器,一键把当前域名丢到 Ahrefs/Similarweb/Google 等工具;支持自定义脚本列表(JSON 管理)。
// ==UserScript== // @name SEO 站长助手(快捷脚本) // @namespace https://yestool.org // @version 1.0.0 // @description 在任意页面右侧浮动一个快捷脚本启动器,一键把当前域名丢到 Ahrefs/Similarweb/Google 等工具;支持自定义脚本列表(JSON 管理)。 // @author https://github.com/yestool // @license MIT // @match *://*/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_openInTab // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // ---------- Utilities ---------- const SKEY = 'qs_scripts_v1'; const HKEY = 'qs_hidden_v1'; // 简易 eTLD+1 近似:常见多段后缀覆盖,其他场景回退为最后两段 const multiPartTLD = new Set([ 'co.uk','org.uk','ac.uk','gov.uk','co.jp','ne.jp','or.jp','com.au','net.au','org.au','co.nz','org.nz','com.br','com.cn','net.cn','org.cn','gov.cn','edu.cn','com.hk','com.sg' ]); function getDomain(hostname) { hostname = (hostname || location.hostname || '').toLowerCase(); if (!hostname) return ''; const parts = hostname.split('.'); if (parts.length <= 2) return hostname; const last2 = parts.slice(-2).join('.'); const last3 = parts.slice(-3).join('.'); if (multiPartTLD.has(last2)) { // xxx.co.uk 场景 -> 取最后三段 return parts.slice(-3).join('.'); } if (multiPartTLD.has(last3)) { // 极少见更长多段,兜底 return parts.slice(-4).join('.'); } // 普通:取最后两段 return last2; } function openTab(url, active = true) { try { GM_openInTab(url, { active, insert: true }); } catch (e) { window.open(url, '_blank'); } } function $(sel, root=document) { return root.querySelector(sel); } // 读取/初始化脚本定义 function defaultScripts() { return [ { name: "Ahrefs Backlink", type: "func", desc: "Ahrefs Backlink查询", code: ` var domain = window.location.hostname; var ahrefsUrl = 'https://ahrefs.com/backlink-checker?input=' + encodeURIComponent(domain) + '&mode=subdomains'; window.open(ahrefsUrl, '_blank'); ` }, { name: "Ahrefs Site Explorer(domain)", type: "urlTemplate", desc: "用当前域名打开 Ahrefs Site Explorer(需已登录(不可用))", urlTemplate: "https://app.ahrefs.com/site-explorer/overview/v2/subdomains/live?target={domain}" }, { name: "Google site:(domain)", type: "urlTemplate", desc: "快速 site: 当前域名", urlTemplate: "https://www.google.com/search?q=site%3A{domain}" }, { name: "Similarweb ", type: "urlTemplate", desc: "查看 Similarweb 站点画像(需已登录(不可用))", urlTemplate: "https://pro.similarweb.com/#/digitalsuite/websiteanalysis/overview/website-performance/*/999/1m?webSource=Total&key={domain}" }, { name: "Ahrefs Keyword Difficulty", type: "func", desc: "Ahrefs KD值查询(仅Google搜索页有效)", code: ` var kw=document.querySelector('textarea[name=q]').value; var ahrefsUrl = 'https://ahrefs.com/keyword-difficulty/?country=us&input=' + encodeURIComponent(kw); window.open(ahrefsUrl, '_blank'); ` } ]; } function readScripts() { let scripts = GM_getValue(SKEY, null); if (!scripts || !Array.isArray(scripts) || scripts.length === 0) { scripts = defaultScripts(); GM_setValue(SKEY, scripts); } return scripts; } function saveScripts(scripts) { if (!Array.isArray(scripts)) return; GM_setValue(SKEY, scripts); } // ---------- UI ---------- // 用 Shadow DOM 隔离样式,避免被站点 CSS 污染 const host = document.createElement('div'); host.id = 'qs-launcher-host'; document.documentElement.appendChild(host); const shadow = host.attachShadow({ mode: 'open' }); const style = document.createElement('style'); style.textContent = ` .qs-wrap{ position: fixed; top: 35%; right: 12px; z-index: 2147483647; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;} .qs-btn{ width: 44px; height: 44px; border-radius: 50%; background: #111; color:#fff; display:flex; align-items:center; justify-content:center; cursor:pointer; box-shadow:0 6px 18px rgba(0,0,0,.25); transition:.2s; } .qs-btn:hover{ transform: translateY(-1px); } .qs-hide{ display:none !important; } .qs-panel{ position: fixed; top: 20%; right: 70px; width: 320px; max-height: 60vh; overflow:auto; background:#fff; color:#111; border:1px solid #e5e7eb; border-radius:12px; box-shadow:0 10px 30px rgba(0,0,0,.15); } .qs-header{ display:flex; align-items:center; justify-content:space-between; padding:10px 12px; border-bottom:1px solid #eee; position:sticky; top:0; background:#fff; z-index:1;} .qs-title{ font-weight:600; font-size:14px;} .qs-actions button{ margin-left:8px; font-size:12px; padding:4px 8px; border:1px solid #e5e7eb; background:#f8fafc; border-radius:8px; cursor:pointer;} .qs-actions button:hover{ background:#eef2f7;} .qs-list{ padding:8px; } .qs-item{ display:flex; flex-direction:column; padding:8px; border-radius:10px; border:1px solid #f1f5f9; margin-bottom:8px; } .qs-item h4{ margin:0 0 6px 0; font-size:14px; } .qs-item p{ margin:0 0 8px 0; font-size:12px; color:#475569;} .qs-run{ align-self:flex-start; padding:6px 10px; border-radius:8px; border:1px solid #e5e7eb; background:#111; color:#fff; cursor:pointer; font-size:12px;} .qs-run:hover{ filter:brightness(1.05); } .qs-empty{ padding:16px; color:#64748b; font-size:13px; } .qs-close{ position:absolute; top:6px; right:8px; background:transparent; border:none; font-size:18px; cursor:pointer; color:#333;} .qs-toggle{ margin-left:8px; font-size:12px; padding:4px 8px; border:1px solid #e5e7eb; background:#fff; border-radius:8px; cursor:pointer;} `; const wrap = document.createElement('div'); wrap.className = 'qs-wrap'; const btn = document.createElement('div'); btn.className = 'qs-btn'; btn.title = '快捷脚本'; btn.textContent = '⚡'; const panel = document.createElement('div'); panel.className = 'qs-panel qs-hide'; panel.innerHTML = ` <div class="qs-header"> <div class="qs-title">快捷脚本</div> <div class="qs-actions"> <button class="qs-manage" title="管理脚本(JSON)">⚙ 管理</button> <button class="qs-hidebtn" title="隐藏浮标">🙈 隐藏</button> </div> <button class="qs-close" title="关闭面板">×</button> </div> <div class="qs-list"></div> `; shadow.append(style, wrap); wrap.append(btn, panel); // 记住隐藏状态 const hidden = GM_getValue(HKEY, false); if (hidden) wrap.classList.add('qs-hide'); // 列表渲染 function renderList() { const list = $('.qs-list', shadow); list.innerHTML = ''; const scripts = readScripts(); if (!scripts.length) { const div = document.createElement('div'); div.className = 'qs-empty'; div.textContent = '暂无脚本,点右上角 “⚙ 管理” 添加。'; list.appendChild(div); return; } const ctx = buildContext(); scripts.forEach((s, idx) => { const item = document.createElement('div'); item.className = 'qs-item'; const h4 = document.createElement('h4'); h4.textContent = s.name || `脚本 #${idx+1}`; const p = document.createElement('p'); p.textContent = s.desc || ''; const run = document.createElement('button'); run.className = 'qs-run'; run.textContent = '执行'; run.addEventListener('click', () => runScript(s, ctx)); item.append(h4, p, run); list.appendChild(item); }); } // 上下文对象 function buildContext() { const hostname = location.hostname; const domain = getDomain(hostname); const selection = String(window.getSelection ? (window.getSelection()+'') : '') || ''; const title = document.title || ''; const url = location.href; return { hostname, domain, selection, title, url }; } // 执行器:两类——urlTemplate / func(字符串函数体) function runScript(s, ctx) { try { if (s.type === 'urlTemplate' && s.urlTemplate) { const finalUrl = s.urlTemplate .replaceAll('{domain}', encodeURIComponent(ctx.domain)) .replaceAll('{hostname}', encodeURIComponent(ctx.hostname)) .replaceAll('{url}', encodeURIComponent(ctx.url)) .replaceAll('{title}', encodeURIComponent(ctx.title)) .replaceAll('{selection}', encodeURIComponent(ctx.selection)); if (!finalUrl || !/^https?:\/\//i.test(finalUrl)) { alert('URL 模板无效'); return; } openTab(finalUrl, true); return; } if (s.type === 'func' && s.code) { // 在 userscript 沙箱中执行,可直接操作 DOM const fn = new Function(s.code); fn.call(window); return; } alert('未知脚本类型或缺少必要字段。'); } catch (e) { console.error('[Quick Scripts] 执行出错:', e); alert('脚本执行失败:' + e.message); } } // 事件绑定 btn.addEventListener('click', () => { panel.classList.toggle('qs-hide'); if (!panel.classList.contains('qs-hide')) renderList(); }); panel.querySelector('.qs-close').addEventListener('click', () => { panel.classList.add('qs-hide'); }); panel.querySelector('.qs-hidebtn').addEventListener('click', () => { wrap.classList.add('qs-hide'); GM_setValue(HKEY, true); }); panel.querySelector('.qs-manage').addEventListener('click', () => { const current = JSON.stringify(readScripts(), null, 2); const next = prompt( '以 JSON 数组形式编辑脚本:\n' + '支持两种类型:\n' + '1) { "name":"xxx", "type":"urlTemplate", "desc":"...", "urlTemplate":"https://...{domain}..." }\n' + '2) { "name":"xxx", "type":"func", "desc":"...", "code":"/* JS 函数体,可用 document.querySelector 等 */" }\n\n' + '当前:', current ); if (next == null) return; try { const parsed = JSON.parse(next); if (!Array.isArray(parsed)) throw new Error('必须是数组'); saveScripts(parsed); alert('已保存。'); renderList(); } catch (e) { alert('JSON 解析失败:' + e.message); } }); // 在页面左下角加一个“显示浮标”的极简入口(当你把浮标隐藏后) function addRestoreBtn() { if ($('#qs-restore', shadow)) return; const r = document.createElement('button'); r.id = 'qs-restore'; r.textContent = '⚡'; r.title = '显示快捷脚本浮标'; r.style.position = 'fixed'; r.style.left = '10px'; r.style.bottom = '10px'; r.style.zIndex = '2147483647'; r.style.width = '36px'; r.style.height = '36px'; r.style.borderRadius = '50%'; r.style.border = '1px solid #e5e7eb'; r.style.background = '#fff'; r.style.cursor = 'pointer'; r.addEventListener('click', () => { wrap.classList.remove('qs-hide'); GM_setValue(HKEY, false); r.remove(); }); shadow.appendChild(r); } if (hidden) addRestoreBtn(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址