您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds auto-scrolling functionality to any website
- // ==UserScript==
- // @name Universal Auto-Scroll
- // @namespace http://tampermonkey.net/
- // @version 1.1
- // @description Adds auto-scrolling functionality to any website
- // @author You
- // @match *://*/*
- // @grant GM_setValue
- // @grant GM_getValue
- // @run-at document-idle
- // ==/UserScript==
- (function() {
- 'use strict';
- // Wait a bit for page to be fully ready
- setTimeout(initAutoScroll, 1000);
- function initAutoScroll() {
- // Configuration
- const DEFAULT_SETTINGS = {
- isActive: false,
- speed: 3,
- isMinimized: false,
- pixelsPerSecond: 50 // Base scrolling speed - will be modified by speed setting
- };
- // State variables
- let isScrolling = false;
- let scrollIntervalId = null;
- let userScrollDetected = false;
- let userScrollTimeout = null;
- let lastScrollPosition = window.scrollY;
- // Load saved settings or use defaults - Using Tampermonkey's built-in storage
- let scrollSettings;
- try {
- scrollSettings = JSON.parse(GM_getValue('autoScrollSettings', JSON.stringify(DEFAULT_SETTINGS)));
- } catch (e) {
- console.log('Could not load settings, using defaults');
- scrollSettings = DEFAULT_SETTINGS;
- }
- // DOM elements references
- let autoScrollPanel;
- let bubbleView;
- let toggleButton;
- let speedSlider;
- let speedValue;
- // Create and inject the UI
- function createUI() {
- // Create a container for our elements with a unique ID
- const containerId = 'auto-scroll-container-' + Math.random().toString(36).substr(2, 9);
- const container = document.createElement('div');
- container.id = containerId;
- document.body.appendChild(container);
- // Add isolated styles to avoid conflicts with page CSS
- const styleElement = document.createElement('style');
- styleElement.textContent = `
- #${containerId} {
- all: initial;
- font-family: Arial, sans-serif;
- color: white;
- font-size: 14px;
- }
- #${containerId} * {
- all: unset;
- box-sizing: border-box;
- }
- #${containerId} .auto-scroll-panel {
- position: fixed;
- bottom: 80px;
- right: 20px;
- background-color: rgba(0, 0, 0, 0.8);
- color: white;
- padding: 15px;
- border-radius: 8px;
- width: 220px;
- z-index: 9999999;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
- font-family: Arial, sans-serif;
- display: ${scrollSettings.isMinimized ? 'none' : 'block'};
- }
- #${containerId} .panel-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 10px;
- border-bottom: 1px solid rgba(255, 255, 255, 0.2);
- padding-bottom: 8px;
- }
- #${containerId} .panel-title {
- font-weight: bold;
- font-size: 16px;
- display: block;
- }
- #${containerId} .minimize-button {
- background: none;
- border: none;
- color: white;
- cursor: pointer;
- font-size: 20px;
- padding: 0;
- margin: 0;
- display: block;
- }
- #${containerId} .section {
- margin-bottom: 12px;
- }
- #${containerId} .section-title {
- font-size: 14px;
- color: #ffcc00;
- margin-bottom: 8px;
- display: block;
- }
- #${containerId} .toggle-button {
- background-color: #2196F3;
- border: none;
- color: white;
- padding: 10px 15px;
- text-align: center;
- text-decoration: none;
- font-size: 14px;
- border-radius: 6px;
- width: 100%;
- cursor: pointer;
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 8px;
- margin-bottom: 10px;
- }
- #${containerId} .toggle-button.active {
- background-color: #4CAF50;
- }
- #${containerId} .slider-container {
- width: 100%;
- display: flex;
- flex-direction: column;
- gap: 8px;
- }
- #${containerId} .slider-top {
- display: flex;
- justify-content: space-between;
- width: 100%;
- }
- #${containerId} .speed-value {
- font-weight: bold;
- }
- #${containerId} .speed-slider {
- width: 100%;
- height: 5px;
- -webkit-appearance: none;
- appearance: none;
- background: #444;
- outline: none;
- border-radius: 3px;
- display: block;
- }
- #${containerId} .speed-slider::-webkit-slider-thumb {
- -webkit-appearance: none;
- appearance: none;
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #ffcc00;
- cursor: pointer;
- }
- #${containerId} .speed-slider::-moz-range-thumb {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: #ffcc00;
- cursor: pointer;
- }
- #${containerId} .slider-labels {
- display: flex;
- justify-content: space-between;
- width: 100%;
- }
- #${containerId} .auto-scroll-bubble {
- position: fixed;
- bottom: 80px;
- right: 20px;
- width: 60px;
- height: 60px;
- border-radius: 50%;
- background-color: rgba(0, 0, 0, 0.8);
- display: ${scrollSettings.isMinimized ? 'flex' : 'none'};
- flex-direction: column;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- z-index: 9999999;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
- font-size: 24px;
- }
- `;
- document.head.appendChild(styleElement);
- // Create the main panel
- autoScrollPanel = document.createElement('div');
- autoScrollPanel.className = 'auto-scroll-panel';
- container.appendChild(autoScrollPanel);
- // Create panel header with title and minimize button
- const panelHeader = document.createElement('div');
- panelHeader.className = 'panel-header';
- const panelTitle = document.createElement('div');
- panelTitle.className = 'panel-title';
- panelTitle.textContent = 'Auto-Scroll Controls';
- const minimizeButton = document.createElement('button');
- minimizeButton.className = 'minimize-button';
- minimizeButton.textContent = '−';
- minimizeButton.addEventListener('click', toggleMinimize);
- panelHeader.appendChild(panelTitle);
- panelHeader.appendChild(minimizeButton);
- autoScrollPanel.appendChild(panelHeader);
- // Create scrolling status section
- const statusSection = document.createElement('div');
- statusSection.className = 'section';
- const statusTitle = document.createElement('div');
- statusTitle.className = 'section-title';
- statusTitle.textContent = 'Scrolling Status';
- toggleButton = document.createElement('button');
- toggleButton.className = 'toggle-button' + (scrollSettings.isActive ? ' active' : '');
- toggleButton.innerHTML = scrollSettings.isActive ?
- '<span>⏸️</span> Pause Scrolling' :
- '<span>▶️</span> Start Scrolling';
- toggleButton.addEventListener('click', toggleScrolling);
- statusSection.appendChild(statusTitle);
- statusSection.appendChild(toggleButton);
- autoScrollPanel.appendChild(statusSection);
- // Create speed control section
- const speedSection = document.createElement('div');
- speedSection.className = 'section';
- const speedTitle = document.createElement('div');
- speedTitle.className = 'section-title';
- speedTitle.textContent = 'Scroll Speed';
- const sliderContainer = document.createElement('div');
- sliderContainer.className = 'slider-container';
- const sliderTop = document.createElement('div');
- sliderTop.className = 'slider-top';
- const speedLabel = document.createElement('span');
- speedLabel.textContent = 'Speed:';
- speedValue = document.createElement('span');
- speedValue.className = 'speed-value';
- updateSpeedDisplay(scrollSettings.speed);
- sliderTop.appendChild(speedLabel);
- sliderTop.appendChild(speedValue);
- speedSlider = document.createElement('input');
- speedSlider.type = 'range';
- speedSlider.className = 'speed-slider';
- speedSlider.min = '1';
- speedSlider.max = '5';
- speedSlider.value = scrollSettings.speed;
- speedSlider.addEventListener('input', handleSpeedChange);
- const sliderLabels = document.createElement('div');
- sliderLabels.className = 'slider-labels';
- const slowLabel = document.createElement('span');
- slowLabel.textContent = 'Slow';
- const fastLabel = document.createElement('span');
- fastLabel.textContent = 'Fast';
- sliderLabels.appendChild(slowLabel);
- sliderLabels.appendChild(fastLabel);
- sliderContainer.appendChild(sliderTop);
- sliderContainer.appendChild(speedSlider);
- sliderContainer.appendChild(sliderLabels);
- speedSection.appendChild(speedTitle);
- speedSection.appendChild(sliderContainer);
- autoScrollPanel.appendChild(speedSection);
- // Create bubble view (minimized version)
- bubbleView = document.createElement('div');
- bubbleView.className = 'auto-scroll-bubble';
- bubbleView.innerHTML = '📜';
- bubbleView.addEventListener('click', toggleMinimize);
- container.appendChild(bubbleView);
- // Start scrolling if it was active before
- if (scrollSettings.isActive) {
- startScrolling();
- }
- }
- // Toggle between expanded panel and minimized bubble
- function toggleMinimize() {
- scrollSettings.isMinimized = !scrollSettings.isMinimized;
- if (scrollSettings.isMinimized) {
- autoScrollPanel.style.display = 'none';
- bubbleView.style.display = 'flex';
- } else {
- autoScrollPanel.style.display = 'block';
- bubbleView.style.display = 'none';
- }
- saveSettings();
- }
- // Toggle scrolling on/off
- function toggleScrolling() {
- scrollSettings.isActive = !scrollSettings.isActive;
- if (scrollSettings.isActive) {
- // Start scrolling
- toggleButton.classList.add('active');
- toggleButton.innerHTML = '<span>⏸️</span> Pause Scrolling';
- startScrolling();
- } else {
- // Pause scrolling
- toggleButton.classList.remove('active');
- toggleButton.innerHTML = '<span>▶️</span> Start Scrolling';
- stopScrolling();
- }
- saveSettings();
- }
- // Handle speed slider changes
- function handleSpeedChange() {
- const value = parseInt(speedSlider.value);
- scrollSettings.speed = value;
- updateSpeedDisplay(value);
- // If currently scrolling, update the scroll speed
- if (isScrolling) {
- stopScrolling();
- startScrolling();
- }
- saveSettings();
- }
- // Update speed display text
- function updateSpeedDisplay(value) {
- let speedText;
- if (value === 1) speedText = "Very Slow";
- else if (value === 2) speedText = "Slow";
- else if (value === 3) speedText = "Medium";
- else if (value === 4) speedText = "Fast";
- else speedText = "Very Fast";
- speedValue.textContent = `${speedText} (${value})`;
- }
- // Start auto-scrolling
- function startScrolling() {
- if (isScrolling) return;
- isScrolling = true;
- lastScrollPosition = window.scrollY;
- // Calculate scroll speed based on setting (1-5)
- // The base speed (pixelsPerSecond) is multiplied by a factor based on the speed setting
- const speedFactors = [0.5, 0.75, 1, 1.5, 2.5]; // Factors for speeds 1-5
- const pixelsPerSecond = DEFAULT_SETTINGS.pixelsPerSecond * speedFactors[scrollSettings.speed - 1];
- // Convert pixels per second to interval delay in milliseconds
- // We'll scroll 1px at a time for smoothness
- const scrollDelay = Math.floor(1000 / pixelsPerSecond);
- // Start scroll interval
- scrollIntervalId = setInterval(function() {
- // Only scroll if user isn't manually scrolling
- if (!userScrollDetected) {
- window.scrollBy(0, 1);
- }
- }, scrollDelay);
- }
- // Stop auto-scrolling
- function stopScrolling() {
- if (!isScrolling) return;
- isScrolling = false;
- if (scrollIntervalId !== null) {
- clearInterval(scrollIntervalId);
- scrollIntervalId = null;
- }
- }
- // Save settings using Tampermonkey's storage
- function saveSettings() {
- try {
- GM_setValue('autoScrollSettings', JSON.stringify(scrollSettings));
- } catch (e) {
- console.error('Failed to save settings:', e);
- }
- }
- // Handle user manual scrolling
- function handleUserScroll() {
- const currentPosition = window.scrollY;
- // If position changed significantly (more than what our auto-scroll would do)
- // and we're currently auto-scrolling, pause temporarily
- if (isScrolling && Math.abs(currentPosition - lastScrollPosition) > 3) {
- userScrollDetected = true;
- // Clear existing timeout if there is one
- if (userScrollTimeout) {
- clearTimeout(userScrollTimeout);
- }
- // Set timeout to resume auto-scrolling after user stops scrolling
- userScrollTimeout = setTimeout(function() {
- userScrollDetected = false;
- lastScrollPosition = window.scrollY;
- }, 5000); // 5-second delay before resuming
- }
- lastScrollPosition = currentPosition;
- }
- // Only create UI if we're on a page with scrollable content
- if (document.body && document.body.scrollHeight > window.innerHeight) {
- createUI();
- // Add scroll event listener to detect manual user scrolling
- window.addEventListener('scroll', handleUserScroll, { passive: true });
- // Clean up when page is unloaded
- window.addEventListener('beforeunload', function() {
- if (scrollIntervalId !== null) {
- clearInterval(scrollIntervalId);
- }
- });
- }
- }
- })();