您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smooth auto-scroll with HUD controls, hotkeys, and site allowlist (dark red theme, compact HUD). Press S to toggle, [ ] adjust speed, + - adjust step, R reset, H hide HUD. Allowlist via console command allowSite("domain"). Manage with listAllowSites(), removeSite("domain"), resetAllowlist(). Console logs info on each domain 👇
// ==UserScript== // @name Enhanced AutoScroll (Red/Black HUD, Allowlist Mode) // @namespace https://greasyfork.org/users/1513610 // @version 3.0 // @description Smooth auto-scroll with HUD controls, hotkeys, and site allowlist (dark red theme, compact HUD). Press S to toggle, [ ] adjust speed, + - adjust step, R reset, H hide HUD. Allowlist via console command allowSite("domain"). Manage with listAllowSites(), removeSite("domain"), resetAllowlist(). Console logs info on each domain 👇 // @author NAABO // @match *://*/* // @grant none // ==/UserScript== /* 📌 Features: - Press 'S' to start/pause smooth scrolling. - '[' / ']' decrease/increase scroll speed. - '+' / '-' adjust speed step size. - 'R' resets to default speed. - 'H' shows/hides the HUD. - Respects "prefers-reduced-motion". 📌 Allowlist Mode: - Script runs ONLY on sites added to the allowlist. - To allowlist a site, open DevTools console and run: allowSite("example.com"); 📌 Console Helpers: - allowSite("example.com") → add a site to allowlist - removeSite("example.com") → remove a site from allowlist - listAllowSites() → list all allowlisted sites - resetAllowlist() → clear the allowlist */ (function () { 'use strict'; /************* Configuration *************/ const CONFIG = { STORAGE_KEY: 'enhanced_autoscroll_config', ALLOWLIST_KEY: 'enhanced_autoscroll_allowlist', DEFAULT_SPEED: 250, DEFAULT_SPEED_STEP: 50, MIN_SPEED_STEP: 10, MAX_SPEED_STEP: 100, HUD_POSITIONS: ['bottom-right', 'bottom-left', 'top-right', 'top-left'], FLASH_DURATION: 1500, }; /************* State *************/ const state = { scrolling: false, speed: CONFIG.DEFAULT_SPEED, speedStep: CONFIG.DEFAULT_SPEED_STEP, hud: null, hudPositionIndex: 0, animationFrame: null, allowlist: JSON.parse(localStorage.getItem(CONFIG.ALLOWLIST_KEY) || '[]'), }; /************* Utils *************/ function saveConfig() { const data = { speed: state.speed, speedStep: state.speedStep, hudPositionIndex: state.hudPositionIndex, }; localStorage.setItem(CONFIG.STORAGE_KEY, JSON.stringify(data)); } function loadConfig() { const data = JSON.parse(localStorage.getItem(CONFIG.STORAGE_KEY) || '{}'); if (data.speed) state.speed = data.speed; if (data.speedStep) state.speedStep = data.speedStep; if (data.hudPositionIndex != null) state.hudPositionIndex = data.hudPositionIndex; } function isAllowedSite() { return state.allowlist.includes(location.hostname); } function allowSite(domain) { if (!domain) domain = location.hostname; if (!state.allowlist.includes(domain)) { state.allowlist.push(domain); localStorage.setItem(CONFIG.ALLOWLIST_KEY, JSON.stringify(state.allowlist)); console.log(`✅ ${domain} added to Enhanced AutoScroll allowlist. Reload the page to activate.`); } else { console.log(`⚠️ ${domain} is already in the allowlist.`); } } function removeSite(domain) { if (!domain) domain = location.hostname; if (state.allowlist.includes(domain)) { state.allowlist = state.allowlist.filter(d => d !== domain); localStorage.setItem(CONFIG.ALLOWLIST_KEY, JSON.stringify(state.allowlist)); console.log(`🗑️ ${domain} removed from Enhanced AutoScroll allowlist.`); } else { console.log(`⚠️ ${domain} was not in the allowlist.`); } } function listAllowSites() { if (!state.allowlist.length) { console.log("📭 Allowlist is empty."); } else { console.log("📜 Enhanced AutoScroll allowlist:"); state.allowlist.forEach((site, i) => { console.log(`${i + 1}. ${site}`); }); } } function resetAllowlist() { state.allowlist = []; localStorage.setItem(CONFIG.ALLOWLIST_KEY, JSON.stringify([])); console.log("♻️ Enhanced AutoScroll allowlist reset to empty."); } // Expose helpers to console window.allowSite = allowSite; window.removeSite = removeSite; window.listAllowSites = listAllowSites; window.resetAllowlist = resetAllowlist; function flashHUD(msg) { if (!state.hud) return; const div = document.createElement('div'); div.textContent = msg; div.style.cssText = ` position:absolute; top:-24px; left:50%; transform:translateX(-50%); background:#b91c1c; color:#fff; padding:3px 6px; border-radius:4px; font-size:11px; pointer-events:none; `; state.hud.appendChild(div); setTimeout(() => div.remove(), CONFIG.FLASH_DURATION); } function getHUDPositionStyles() { switch (CONFIG.HUD_POSITIONS[state.hudPositionIndex]) { case 'bottom-left': return 'bottom:12px; left:12px;'; case 'top-right': return 'top:12px; right:12px;'; case 'top-left': return 'top:12px; left:12px;'; default: return 'bottom:12px; right:12px;'; } } /************* HUD *************/ function createHUD() { if (state.hud) state.hud.remove(); state.hud = document.createElement('div'); state.hud.id = 'enhanced-autoscroll-hud'; state.hud.style.cssText = ` position:fixed; ${getHUDPositionStyles()} z-index:999999; padding:8px 10px; background:#111; color:#fff; font-family:monospace, system-ui, sans-serif; font-size:12px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.6); border:1px solid #b91c1c; opacity:0.95; max-width:300px; `; state.hud.innerHTML = ` <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:6px;"> <div id="hud-status" style="font-weight:bold; font-size:12px; color:#ef4444;">PAUSED</div> <button id="hud-close" style=" background:none; border:none; color:#ef4444; font-size:14px; cursor:pointer; padding:0; line-height:1; " title="Close">×</button> </div> <div id="hud-speed" style="margin-bottom:6px; font-size:11px; color:#aaa;"></div> <div id="hud-buttons" style="display:flex; flex-wrap:wrap; gap:4px;"> ${makeButton("S", "toggle", "Toggle scroll")} ${makeButton("[", "speed-down", "Decrease speed")} ${makeButton("]", "speed-up", "Increase speed")} ${makeButton("R", "reset", "Reset speed")} ${makeButton("H", "hide-hud", "Hide HUD")} ${makeButton("+", "step-up", "Increase step")} ${makeButton("-", "step-down", "Decrease step")} </div> `; document.body.appendChild(state.hud); state.hud.querySelector('#hud-close').addEventListener('click', shutdownScript); setupHUDButtons(); updateHUD(); } function makeButton(label, action, title) { return ` <button class="hud-btn" data-action="${action}" title="${title}" style=" background:#1a1a1a; border:1px solid #b91c1c; color:#f87171; font-size:12px; padding:2px 6px; border-radius:4px; cursor:pointer; transition:all 0.2s; " onmouseover="this.style.background='#b91c1c'; this.style.color='#fff';" onmouseout="this.style.background='#1a1a1a'; this.style.color='#f87171';" >${label}</button> `; } function setupHUDButtons() { state.hud.querySelectorAll('.hud-btn').forEach(btn => { btn.addEventListener('click', () => { handleAction(btn.dataset.action); }); }); } function updateHUD() { if (!state.hud) return; const status = state.hud.querySelector('#hud-status'); status.textContent = state.scrolling ? 'SCROLLING' : 'PAUSED'; status.style.color = state.scrolling ? '#22c55e' : '#ef4444'; state.hud.querySelector('#hud-speed').textContent = `Speed: ${state.speed}px/s | Step: ${state.speedStep}`; } /************* Core *************/ function handleAction(action) { switch (action) { case 'toggle': toggleScroll(); break; case 'speed-down': changeSpeed(-state.speedStep); break; case 'speed-up': changeSpeed(state.speedStep); break; case 'reset': resetSpeed(); break; case 'hide-hud': toggleHUD(); break; case 'step-up': changeStep(1); break; case 'step-down': changeStep(-1); break; } saveConfig(); updateHUD(); } function toggleScroll() { state.scrolling = !state.scrolling; if (state.scrolling) requestScroll(); else cancelAnimationFrame(state.animationFrame); updateHUD(); } function changeSpeed(delta) { state.speed = Math.max(0, state.speed + delta); flashHUD(`Speed: ${state.speed}px/s`); } function resetSpeed() { state.speed = CONFIG.DEFAULT_SPEED; flashHUD("🔄 Speed reset"); } function changeStep(delta) { state.speedStep = Math.min(CONFIG.MAX_SPEED_STEP, Math.max(CONFIG.MIN_SPEED_STEP, state.speedStep + delta)); flashHUD(`Step: ${state.speedStep}`); } function toggleHUD() { state.hud.style.display = state.hud.style.display === 'none' ? '' : 'none'; } function requestScroll() { const step = state.speed / 60; window.scrollBy(0, step); state.animationFrame = requestAnimationFrame(requestScroll); } function shutdownScript() { cancelAnimationFrame(state.animationFrame); if (state.hud) state.hud.remove(); document.removeEventListener('keydown', keyHandler); } /************* Keyboard *************/ function keyHandler(e) { if (['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) return; switch (e.key) { case 's': case 'S': handleAction('toggle'); break; case '[': handleAction('speed-down'); break; case ']': handleAction('speed-up'); break; case 'r': case 'R': handleAction('reset'); break; case 'h': case 'H': handleAction('hide-hud'); break; case '+': case '=': handleAction('step-up'); break; case '-': case '_': handleAction('step-down'); break; } } /************* Init *************/ function init() { if (!isAllowedSite()) { console.log(`⚪ Enhanced AutoScroll inactive on ${location.hostname}`); console.log(`👉 To allowlist, run: allowSite("${location.hostname}")`); console.log(`👉 To list allowlisted sites, run: listAllowSites()`); return; } console.log(`✅ Enhanced AutoScroll active on ${location.hostname}`); console.log(`⚙️ Console helpers: allowSite("${location.hostname}"), removeSite("${location.hostname}"), listAllowSites(), resetAllowlist()`); loadConfig(); createHUD(); document.addEventListener('keydown', keyHandler); updateHUD(); } init(); })();