您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动将TouchGal网站上的VNDB ID转换为可点击的链接
// ==UserScript== // @name TouchGal VNDB链接转换器 // @namespace https://github.com/dccif // @version 1.0.6 // @author dccif // @description 自动将TouchGal网站上的VNDB ID转换为可点击的链接 // @license MIT // @icon https://www.touchgal.us/favicon.ico // @source https://github.com/dccif/touchgal-script.git // @match https://www.touchgal.io/* // @match https://www.touchgal.us/* // @grant none // @run-at document-idle // ==/UserScript== (function () { 'use strict'; let executed = false; let stylesCached = false; let cachedRefClass = ""; let cachedRefRole = null; let styleAttempts = 0; let vndbAttempts = 0; let pollCount = 0; let currentInterval = 300; const maxStyleAttempts = 5; const maxVndbAttempts = 8; const maxPollCount = 30; const intervals = [300, 500, 800, 1200, 2e3]; function shouldRun() { const { href, pathname } = location; return href.includes("?") || href.includes("#") || pathname !== "/"; } function tryCacheStyles() { if (stylesCached || styleAttempts >= maxStyleAttempts) return; styleAttempts++; const refLink = document.querySelector(".kun-prose a"); if (refLink) { cachedRefClass = refLink.className || ""; cachedRefRole = refLink.getAttribute("role"); stylesCached = true; console.log("✅ 样式信息已缓存"); } else if (styleAttempts >= maxStyleAttempts) { stylesCached = true; console.log("⚠️ 未找到参考样式,使用默认样式"); } } function isPageReady() { const hasGrid = document.querySelector('div[class*="grid"]'); const hasFlex = document.querySelector('div[class*="flex"]'); return !!(hasGrid && hasFlex); } function replaceVNDBIds() { if (executed) return true; vndbAttempts++; const vndbSpans = document.querySelectorAll("span"); if (!vndbSpans.length) { if (vndbAttempts >= maxVndbAttempts) { console.log("⚠️ 多次尝试后未找到VNDB ID,页面上可能没有相关内容"); return true; } return false; } const vndbRegex = /VNDB ID:\s*(v\d+)/; let hasChanges = false; for (let i = 0; i < vndbSpans.length; i++) { const span = vndbSpans[i]; const text = span.textContent; if (!(text == null ? void 0 : text.includes("VNDB ID:"))) continue; const match = text.match(vndbRegex); if (!match) continue; const vndbId = match[1]; const parentNode = span.parentNode; if (parentNode) { const fragment = document.createDocumentFragment(); fragment.appendChild(document.createTextNode("VNDB ID: ")); const link = document.createElement("a"); link.href = `https://vndb.org/${vndbId}`; link.textContent = vndbId; link.target = "_blank"; link.rel = "noopener noreferrer"; if (cachedRefClass) { link.className = cachedRefClass; } if (cachedRefRole) { link.setAttribute("role", cachedRefRole); } fragment.appendChild(link); parentNode.replaceChild(fragment, span); hasChanges = true; console.log(`替换VNDB ID: ${vndbId}`); } } if (hasChanges) { executed = true; console.log("✅ VNDB链接替换完成"); return true; } if (vndbAttempts >= maxVndbAttempts) { console.log("⚠️ 多次尝试后未找到VNDB ID,页面上可能没有相关内容"); return true; } return false; } function execute() { if (!shouldRun() || executed) return; tryCacheStyles(); if (!isPageReady()) return; if (!stylesCached) return; const shouldStop = replaceVNDBIds(); if (shouldStop) { executed = true; } } function poll() { pollCount++; if (pollCount > maxPollCount) { console.log("⚠️ 轮询超时,停止执行"); return; } execute(); if (!executed) { const intervalIndex = Math.min( Math.floor(pollCount / 6), intervals.length - 1 ); currentInterval = intervals[intervalIndex]; console.log(`🔄 轮询第${pollCount}次,间隔${currentInterval}ms`); setTimeout(poll, currentInterval); } } poll(); })();