您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smooth auto-scroll with HUD controls, hotkeys, and site blocklist (dark red theme, compact HUD). Press S to toggle, [ ] adjust speed, + - adjust step, R reset, H hide HUD, 🚫 block site.
当前为
// ==UserScript== // @name Enhanced AutoScroll (Red/Black HUD) // @namespace https://greatest.deepsurf.us/users/1513610 // @version 2.22 // @description Smooth auto-scroll with HUD controls, hotkeys, and site blocklist (dark red theme, compact HUD). Press S to toggle, [ ] adjust speed, + - adjust step, R reset, H hide HUD, 🚫 block site. // @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. - HUD includes buttons for controls + 🚫 blocklist per site. - Respects "prefers-reduced-motion". 📌 Utility Snippets (for console): // Reset Enhanced AutoScroll blocklist to empty localStorage.setItem('enhanced_autoscroll_blocklist', JSON.stringify([])); console.log("✅ Enhanced AutoScroll blocklist reset to empty!"); */ (function () { 'use strict'; /************* Configuration *************/ const CONFIG = { STORAGE_KEY: 'enhanced_autoscroll_config', BLOCKLIST_KEY: 'enhanced_autoscroll_blocklist', DEFAULT_SPEED: 500, 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, blocklist: JSON.parse(localStorage.getItem(CONFIG.BLOCKLIST_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 isBlockedSite() { return state.blocklist.includes(location.hostname); } function blockCurrentSite() { if (state.blocklist.includes(location.hostname)) { flashHUD("⚠️ Already blocked"); return; } const ok = confirm(`🚫 Block auto-scroll on:\n\n${location.hostname}\n\nAre you sure?`); if (ok) { state.blocklist.push(location.hostname); localStorage.setItem(CONFIG.BLOCKLIST_KEY, JSON.stringify(state.blocklist)); flashHUD("✅ Site blocked!"); shutdownScript(); } else { flashHUD("❎ Block canceled"); } } 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")} ${makeButton("🚫", "block-site", "Block this site")} </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; case 'block-site': blockCurrentSite(); 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 (isBlockedSite()) { console.log(`🚫 Enhanced AutoScroll disabled on ${location.hostname} (blocked site).`); return; } loadConfig(); createHUD(); document.addEventListener('keydown', keyHandler); updateHUD(); } init(); })();