自动滚动页面 (和谐共存版)

极致平滑滚动,并且能智能检测用户手动操作,实现和谐共存。

当前为 2025-08-23 提交的版本,查看 最新版本

// ==UserScript==
// @name         自动滚动页面 (和谐共存版)
// @namespace    http://tampermonkey.net/
// @version      0.7
// @description  极致平滑滚动,并且能智能检测用户手动操作,实现和谐共存。
// @author       Leeyw & Cjz & Gemini
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==
(function() {
    'use strict';

    const SYNC_THRESHOLD = 5; // 同步阈值(像素),用于检测用户手动滚动

    let scrolling = false;
    let scrollSpeed = 30; // 默认速度 30 像素/秒
    let deleted = false;
    let targetScrollY = 0; // 记录理想的、带小数的滚动位置
    let lastTimestamp = 0; // 用于存储上一帧的时间戳

    // 自动清除本地存储中的插件配置信息
    localStorage.removeItem('autoScrollEnabled');

    const controlPanel = document.createElement('div');
    controlPanel.style.position = 'fixed';
    controlPanel.style.right = '10px';
    controlPanel.style.bottom = '10px';
    controlPanel.style.zIndex = '1000';
    controlPanel.style.padding = '10px';
    controlPanel.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
    controlPanel.style.borderRadius = '5px';
    controlPanel.style.color = 'white';

    const speedInput = document.createElement('input');
    speedInput.type = 'number';
    speedInput.step = '1';
    speedInput.value = scrollSpeed;
    speedInput.style.width = '50px';

    const startStopButton = document.createElement('button');
    startStopButton.textContent = '开始';

    const deleteButton = document.createElement('button');
    deleteButton.textContent = '删除';

    controlPanel.appendChild(document.createTextNode('速度 (px/s): '));
    controlPanel.appendChild(speedInput);
    controlPanel.appendChild(document.createElement('br'));
    controlPanel.appendChild(startStopButton);
    controlPanel.appendChild(deleteButton);

    document.body.appendChild(controlPanel);

    startStopButton.addEventListener('click', () => {
        scrolling = !scrolling;
        startStopButton.textContent = scrolling ? '停止' : '开始';
        if (scrolling) {
            lastTimestamp = 0;
            targetScrollY = window.scrollY; // 核心:初始化理想位置为当前位置
            window.requestAnimationFrame(autoScroll);
        }
        // 保存配置信息到本地存储
        saveConfig();
    });

    deleteButton.addEventListener('click', () => {
        // ... (省略)
    });

    speedInput.addEventListener('change', () => {
        scrollSpeed = parseFloat(speedInput.value);
        saveConfig();
    });

    function autoScroll(timestamp) {
        if (!scrolling) {
            return;
        }

        if (!lastTimestamp) {
            lastTimestamp = timestamp;
            window.requestAnimationFrame(autoScroll);
            return;
        }

        // --- 开始:新增的同步逻辑 ---
        const actualScrollY = window.scrollY;
        // 检查实际位置和目标位置的差距是否超过阈值
        if (Math.abs(actualScrollY - targetScrollY) > SYNC_THRESHOLD) {
            // 如果超过,说明用户手动滚动了,立即同步目标位置
            targetScrollY = actualScrollY;
        }
        // --- 结束:新增的同步逻辑 ---

        const deltaTime = (timestamp - lastTimestamp) / 1000;
        lastTimestamp = timestamp;

        // 从同步后的新位置继续计算
        targetScrollY += scrollSpeed * deltaTime;
        window.scrollTo(0, targetScrollY);

        window.requestAnimationFrame(autoScroll);
    }

    // ... (此处省略部分未修改代码以保持简洁)
    deleteButton.addEventListener('click', () => {
        localStorage.removeItem('autoScrollEnabled');
        deleted = true;
        controlPanel.remove();
    });
    const saveConfig = () => {
        localStorage.setItem('autoScrollEnabled', JSON.stringify(scrolling));
    };
    if (deleted) {
        return;
    }
    const loadConfig = () => {
        const enabled = JSON.parse(localStorage.getItem('autoScrollEnabled'));
        if (enabled !== null) {
            scrolling = enabled;
            startStopButton.textContent = scrolling ? '停止' : '开始';
            if (scrolling) {
                window.requestAnimationFrame(autoScroll);
            }
        }
    };
    loadConfig();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址