您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在洛谷问题页面的特定位置添加一个跳转到 VJudge 的链接,并与“展开”按钮样式一致
当前为
// ==UserScript== // @name 洛谷到 VJudge 跳转脚本 // @namespace http://tampermonkey.net/ // @version 1.2 // @description 在洛谷问题页面的特定位置添加一个跳转到 VJudge 的链接,并与“展开”按钮样式一致 // @author Kimi // @match https://www.luogu.com.cn/problem/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 函数:生成 VJudge 的问题 URL function generateVJudgeURL(problemCode) { const vjudgePrefix = "洛谷-"; const vjudgeProblemName = encodeURIComponent(vjudgePrefix + problemCode); return `https://vjudge.net/problem/${vjudgeProblemName}`; } // 函数:提取洛谷的问题编号 function getProblemCode() { const urlPath = window.location.pathname; const problemMatch = urlPath.match(/\/problem\/([PB]\d+)/i); if (!problemMatch) { console.warn("无法识别的问题编号格式。"); return null; } return problemMatch[1].toUpperCase(); // 如 P8306 或 B1001 } // 函数:创建跳转按钮 function createVJudgeButton(vjudgeURL) { // 创建 <a> 元素 const link = document.createElement('a'); link.href = vjudgeURL; link.target = '_blank'; // 在新标签页打开 link.className = 'hide-side color-default'; // 与“展开”按钮相同的类名 // 创建 <span> 元素 const span = document.createElement('span'); // 创建 SVG 图标(使用与“展开”按钮相同的图标,或选择其他合适的图标) const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("aria-hidden", "true"); svg.setAttribute("focusable", "false"); svg.setAttribute("data-prefix", "fas"); svg.setAttribute("data-icon", "external-link-alt"); // 选择一个合适的图标 svg.setAttribute("role", "img"); svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"); svg.setAttribute("viewBox", "0 0 512 512"); svg.classList.add("svg-inline--fa", "fa-external-link-alt"); const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); path.setAttribute("fill", "currentColor"); path.setAttribute("d", "M432 320h-32v-32c0-17.7-14.3-32-32-32h-96c-17.7 0-32 14.3-32 32v32h-32c-17.7 0-32 14.3-32 32v128c0 17.7 14.3 32 32 32h128c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32zm-80-160h96v32h-96V160z"); svg.appendChild(path); // 设置图标的大小 svg.style.width = '1em'; svg.style.height = '1em'; svg.style.marginRight = '5px'; // 图标与文字之间的间距 // 设置按钮文本 const text = document.createTextNode('在 VJudge 上查看'); // 组装 <span> span.appendChild(svg); span.appendChild(text); // 组装 <a> link.appendChild(span); return link; } // 函数:插入按钮到指定的 <div class="action"> function insertButton() { const problemCode = getProblemCode(); if (!problemCode) return; const vjudgeURL = generateVJudgeURL(problemCode); // 查找目标 <div class="action"> const actionDiv = document.querySelector('div.action'); if (actionDiv) { // 检查是否已经添加过按钮,避免重复 if (actionDiv.querySelector('.vjudge-link')) { console.warn("VJudge 跳转链接已存在。"); return; } const vjudgeButton = createVJudgeButton(vjudgeURL); vjudgeButton.classList.add('vjudge-link'); // 添加额外类名以便识别 actionDiv.appendChild(vjudgeButton); console.log(`已添加 VJudge 跳转链接: ${vjudgeURL}`); } else { console.warn("未找到 <div class=\"action\"> 元素。"); } } // 等待页面完全加载后执行 window.addEventListener('load', insertButton); // 处理单页面应用(SPA)可能的动态内容加载 // 使用 MutationObserver 监听 DOM 变化,确保在动态加载的情况下也能插入按钮 const observer = new MutationObserver((mutations, obs) => { const actionDiv = document.querySelector('div.action'); if (actionDiv && !actionDiv.querySelector('.vjudge-link')) { insertButton(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();