您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add a button to jump to a random file entry
// ==UserScript== // @name StackStorage Random Entry Button // @namespace Violentmonkey Scripts // @match *://*.stackstorage.com/en/files/* // @grant none // @version 1.4 // @license MIT // @author JasperV // @description Add a button to jump to a random file entry // ==/UserScript== const FLAG_NAME = 'randomClick'; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function waitForSelector(selector, callback, maxWait = 10000) { const start = Date.now(); const interval = setInterval(() => { const el = document.querySelector(selector); if (el) { clearInterval(interval); callback(el); } else if (Date.now() - start > maxWait) { clearInterval(interval); console.warn(`Timeout waiting for selector: ${selector}`); } }, 300); } function hasRandomClickFlag() { return new URLSearchParams(window.location.search).has(FLAG_NAME); } function removeFlagFromURL() { const url = new URL(window.location.href); url.searchParams.delete(FLAG_NAME); window.history.replaceState(null, '', url.toString()); } function clickRandomEntry() { waitForSelector('.grid .grid-row', () => { const rows = document.querySelectorAll('.grid .grid-row'); if (rows.length > 0) { const randomRow = rows[getRandomInt(0, rows.length - 1)]; const link = randomRow.querySelector('a'); if (link) { removeFlagFromURL(); link.click(); } } }); } function getFilelistId() { const match = window.location.pathname.match(/\/files\/(\d+)/); return match ? match[1] : null; } function goToRandomPage() { waitForSelector('.grid', () => { const pagination = document.querySelector('.pagination'); // If pagination doesn't exist, only one page — trigger click directly if (!pagination) { const filelistId = getFilelistId(); if (filelistId) { const url = new URL(window.location.href); url.searchParams.set(FLAG_NAME, '1'); window.history.replaceState(null, '', url.toString()); clickRandomEntry(); } return; } // With pagination const pageLinks = pagination.querySelectorAll('.page-item a.page-link'); if (!pageLinks.length) return; const lastPageHref = pageLinks[pageLinks.length - 1].getAttribute('href'); const match = lastPageHref.match(/\/files\/\d+\/(\d+)/); if (!match) return; const maxPage = parseInt(match[1], 10); const filelistId = getFilelistId(); if (!filelistId) return; const currentMatch = window.location.pathname.match(/\/files\/\d+\/(\d+)/); const currentPage = currentMatch ? parseInt(currentMatch[1], 10) : 1; let randomPage; do { randomPage = getRandomInt(1, maxPage); } while (randomPage === currentPage && maxPage > 1); const newUrl = `/en/files/${filelistId}/${randomPage}?${FLAG_NAME}=1`; window.location.href = newUrl; }); } function addRandomButton() { const buttonsContainer = document.querySelector('.buttons.col-lg-5'); if (!buttonsContainer) return; const button = document.createElement('button'); button.className = 'btn btn-secondary me-2 my-1'; button.innerHTML = '🎲 Random Entry'; button.addEventListener('click', goToRandomPage); buttonsContainer.insertBefore(button, buttonsContainer.firstChild); } // Add button after DOM loads waitForSelector('.buttons.col-lg-5', addRandomButton); // Perform random entry click if flag is set if (hasRandomClickFlag()) { clickRandomEntry(); }