Greasy Fork 支持简体中文。

Universal Auto Scroll

Press Alt + X to start auto-scroll or increase speed. X to pause/resume, Space / Esc to stop. Use Up/Down to adjust speed. Page Up/Down work normally during scroll/pause. Mouse Up/Down pauses during scroll and work normally during pause.

  1. // ==UserScript==
  2. // @name Universal Auto Scroll
  3. // @version 2.0
  4. // @namespace MedX-AA
  5. // @author MedX
  6. // @license MIT
  7. // @description Press Alt + X to start auto-scroll or increase speed. X to pause/resume, Space / Esc to stop. Use Up/Down to adjust speed. Page Up/Down work normally during scroll/pause. Mouse Up/Down pauses during scroll and work normally during pause.
  8. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABGUlEQVR4nO3VsS4EURQG4E9oRCEh0ZDQi3gDjV7lHXTeAYVo9gl0ahregEapoKEh0SFRbVbIyiSjEYnd2TtzZ5PzJSeZYjbzn/2LQwghlSN8oP/PFO8caqHeAOF/pni3dfpDTuvEArlFA7lFA7lFA7lFA7lFA7lFA7lFA7lFA7m1uoE9dCuErDrd8pvJvDYYvl/OS8oFOhkW6KRcYBKnDYY/x5TEpnHZQPhrzKjJLG5qDH+LOTVbxGMN4Z+xrCGreEsY/h3rGraR6Db0sCmTLXyOEP4L2zLbGWGBXS1xUCH8vhaZwPEQ4U/K37RKca3PBgh/UceVTXmtr3Jd2VTmcfdH+HssGBNLePp1ZVeMmTU8lP988RxCkN43yek7CExEuggAAAAASUVORK5CYII=
  9. // @grant none
  10. // @include *
  11. // ==/UserScript==
  12.  
  13. // === CONFIGURATION ===
  14. const INITIAL_SPEED = 30; // Pixels per second
  15. const SPEED_MULTIPLIER = 2.0; // Speed increase factor
  16. const SLOWDOWN_MULTIPLIER = 0.5; // Speed decrease factor
  17.  
  18. // === KEY BINDINGS ===
  19. const START_KEY = 88; // Alt + X starts/increases speed
  20. const PAUSE_KEY = 88; // X pauses/resumes (only while scrolling)
  21. const STOP_KEYS = new Set([27, 32]); // Escape & Space both fully stop scrolling
  22.  
  23. const SCROLL_DOWN_KEYS = new Set([40]); // Down Arrow (Speeds up)
  24. const SCROLL_UP_KEYS = new Set([38]); // Up Arrow (Slows down)
  25. const PAGE_KEYS = new Set([33, 34]); // Page Up, Page Down (Pass-through)
  26.  
  27. let isScrolling = false, isPaused = false, scrollSpeed = 0, lastUpdateTime, realY;
  28. const scrollElement = document.scrollingElement || document.documentElement;
  29. let hudTimeout;
  30.  
  31. // === HUD DISPLAY ===
  32. const hud = Object.assign(document.createElement("div"), {
  33. style: `position:fixed; bottom:10px; right:10px; padding:5px 10px; background:rgba(0,0,0,0.7);
  34. color:#fff; font-size:14px; font-family:Arial; border-radius:5px; z-index:9999; display:none`
  35. });
  36. document.body.appendChild(hud);
  37.  
  38. // === EVENT LISTENERS ===
  39. window.addEventListener('keydown', (e) => {
  40. if (e.ctrlKey || e.shiftKey) return; // Prevent conflicts with other shortcuts
  41.  
  42. if (e.keyCode === START_KEY && e.altKey) {
  43. e.preventDefault();
  44. isScrolling ? changeSpeed(SPEED_MULTIPLIER) : startScrolling();
  45. } else if (isScrolling) {
  46. if (e.keyCode === PAUSE_KEY) {
  47. e.preventDefault();
  48. togglePause();
  49. } else if (STOP_KEYS.has(e.keyCode)) {
  50. e.preventDefault();
  51. stopScrolling();
  52. } else if (SCROLL_DOWN_KEYS.has(e.keyCode)) {
  53. e.preventDefault();
  54. changeSpeed(SPEED_MULTIPLIER);
  55. } else if (SCROLL_UP_KEYS.has(e.keyCode)) {
  56. e.preventDefault();
  57. changeSpeed(SLOWDOWN_MULTIPLIER);
  58. } else if (PAGE_KEYS.has(e.keyCode)) {
  59. realY = scrollElement.scrollTop; // ✅ Updates memory only (no pausing)
  60. }
  61. } else if (isPaused) {
  62. if (PAGE_KEYS.has(e.keyCode) || SCROLL_DOWN_KEYS.has(e.keyCode) || SCROLL_UP_KEYS.has(e.keyCode)) {
  63. realY = scrollElement.scrollTop; // ✅ Updates memory but does not resume
  64. } else if (e.keyCode === PAUSE_KEY) {
  65. togglePause();
  66. } else if (STOP_KEYS.has(e.keyCode)) {
  67. e.preventDefault();
  68. stopScrolling();
  69. }
  70. }
  71. }, { capture: true });
  72.  
  73. // === DETECT MOUSE WHEEL SCROLLING ===
  74. window.addEventListener('wheel', (e) => {
  75. if (isScrolling) {
  76. e.preventDefault();
  77. isPaused = true;
  78. updateHUD();
  79. } else {
  80. realY = scrollElement.scrollTop; // ✅ Always update memory during pause
  81. }
  82. }, { passive: true });
  83.  
  84. // === DETECT MANUAL PAGE UP / PAGE DOWN SCROLLING ===
  85. window.addEventListener('scroll', () => {
  86. if (isPaused || isScrolling) {
  87. realY = scrollElement.scrollTop; // ✅ Always update memory on manual scroll
  88. }
  89. }, { passive: true });
  90.  
  91. // === TOGGLE PAUSE/RESUME ===
  92. const togglePause = () => {
  93. isPaused = !isPaused;
  94. updateHUD();
  95. if (!isPaused) {
  96. lastUpdateTime = performance.now(); // Prevents jumps after resuming
  97. requestAnimationFrame(scrollLoop);
  98. }
  99. };
  100.  
  101. // === CHANGE SCROLL SPEED ===
  102. const changeSpeed = (multiplier) => {
  103. scrollSpeed = Math.max(5, scrollSpeed * multiplier);
  104. updateHUD();
  105. };
  106.  
  107. // === START AUTO-SCROLLING ===
  108. const startScrolling = () => {
  109. isScrolling = true;
  110. isPaused = false;
  111. scrollSpeed = INITIAL_SPEED;
  112. realY = scrollElement.scrollTop;
  113. lastUpdateTime = performance.now();
  114. updateHUD();
  115. requestAnimationFrame(scrollLoop);
  116. };
  117.  
  118. // === STOP AUTO-SCROLLING ===
  119. const stopScrolling = () => {
  120. isScrolling = isPaused = false;
  121. scrollSpeed = 0;
  122. hud.style.display = "none";
  123. };
  124.  
  125. // === MAIN SCROLL LOOP ===
  126. const scrollLoop = (timestamp) => {
  127. if (!isScrolling || isPaused) return;
  128. realY += (scrollSpeed * (timestamp - lastUpdateTime)) / 1000;
  129. scrollElement.scrollTop = Math.floor(realY);
  130. lastUpdateTime = timestamp;
  131. requestAnimationFrame(scrollLoop);
  132. };
  133.  
  134. // === HUD DISPLAY FUNCTION ===
  135. const updateHUD = () => {
  136. hud.textContent = isPaused
  137. ? `PAUSED (Speed: ${scrollSpeed.toFixed(1)} px/s)`
  138. : `Speed: ${scrollSpeed.toFixed(1)} px/s`;
  139. hud.style.display = "block";
  140. clearTimeout(hudTimeout);
  141. if (!isPaused) hudTimeout = setTimeout(() => (hud.style.display = "none"), 2000);
  142. };