您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
支持向上/向下滑动,可调步长与间隔,滑动到顶/底自动停止,状态精准同步
// ==UserScript== // @name 缓慢滑动网页(支持上下滑动 + 可调参数) // @namespace http://tampermonkey.net/ // @version 1.5 // @description 支持向上/向下滑动,可调步长与间隔,滑动到顶/底自动停止,状态精准同步 // @author You // @match *://*/* // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; // 默认配置 let scrollStep = 5; // 每步滚动像素 let scrollInterval = 50; // 每次滚动间隔(毫秒) let scrollDirection = 'down'; // 当前方向:'down' 或 'up' // 全局状态 let isScrolling = false; let isInitialized = false; // 公共样式基础 const baseStyle = ` font-family: Arial, sans-serif; border: none; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; `; /** * 创建所有控制 UI:参数调节 + 方向选择 + 开关按钮 */ function createControls() { if (document.getElementById('tm-scroll-controls') || isInitialized) return; isInitialized = true; // 主容器 const container = document.createElement('div'); container.id = 'tm-scroll-controls'; container.style.cssText = ` position: fixed; bottom: 110px; right: 20px; z-index: 99999; width: 200px; background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); padding: 12px; font-family: Arial, sans-serif; user-select: none; `; // 标题 const title = document.createElement('div'); title.textContent = '自动滑动设置'; title.style.cssText = 'font-weight: bold; margin-bottom: 8px; color: #333; font-size: 14px;'; container.appendChild(title); // 步长调节 container.appendChild(createLabeledSlider('步长(px)', 'step', 1, 20, 1, scrollStep, (val) => { scrollStep = parseInt(val); })); // 间隔调节 container.appendChild(createLabeledSlider('间隔(ms)', 'interval', 10, 200, 10, scrollInterval, (val) => { scrollInterval = parseInt(val); })); // 方向选择按钮 const directionDiv = document.createElement('div'); directionDiv.style.margin = '10px 0 0 0'; directionDiv.innerHTML = ` <span style="font-size:12px;color:#555;display:inline-block;width:50px;">方向</span> <button id="scroll-dir-up" style="${baseStyle} background:#e0e0e0; width:40px; height:24px; margin-left:4px; font-size:12px;">↑</button> <button id="scroll-dir-down" style="${baseStyle} background:#4CAF50; width:40px; height:24px; margin:0 4px; font-size:12px; color:white;">↓</button> `; container.appendChild(directionDiv); // 绑定方向按钮事件 const btnUp = container.querySelector('#scroll-dir-up'); const btnDown = container.querySelector('#scroll-dir-down'); btnUp.onclick = () => { scrollDirection = 'up'; btnUp.style.background = '#4CAF50'; btnUp.style.color = 'white'; btnDown.style.background = '#e0e0e0'; btnDown.style.color = 'black'; updateButtonUI(); // 更新主按钮文字 }; btnDown.onclick = () => { scrollDirection = 'down'; btnDown.style.background = '#4CAF50'; btnDown.style.color = 'white'; btnUp.style.background = '#e0e0e0'; btnUp.style.color = 'black'; updateButtonUI(); // 更新主按钮文字 }; document.body.appendChild(container); // 创建主开关按钮 createToggleButton(); } /** * 创建带 +/- 按钮的调节项 */ function createLabeledSlider(label, idSuffix, min, max, step, value, onChange) { const div = document.createElement('div'); div.style.margin = '8px 0'; div.innerHTML = ` <span style="display:inline-block;width:50px;font-size:12px;color:#555;">${label}</span> <button data-action="decr" style="${baseStyle} background:#f8f8f8; width:24px; height:24px; margin-left:4px;">−</button> <input type="number" id="scroll-${idSuffix}" value="${value}" min="${min}" max="${max}" step="${step}" style="width:50px; height:24px; text-align:center; border:1px solid #ddd; border-radius:4px; margin:0 4px; padding:0; font-size:12px;"> <button data-action="incr" style="${baseStyle} background:#f8f8f8; width:24px; height:24px;">+</button> `; const input = div.querySelector('input'); const decrBtn = div.querySelector('[data-action="decr"]'); const incrBtn = div.querySelector('[data-action="incr"]'); input.addEventListener('change', () => { let val = parseInt(input.value) || parseInt(input.defaultValue); val = Math.max(min, Math.min(max, val)); input.value = val; onChange(val); }); decrBtn.addEventListener('click', () => { let val = Math.max(min, parseInt(input.value) - step); input.value = val; onChange(val); }); incrBtn.addEventListener('click', () => { let val = Math.min(max, parseInt(input.value) + step); input.value = val; onChange(val); }); return div; } /** * 创建主开关按钮 */ function createToggleButton() { const button = document.createElement('button'); button.id = 'tm-scroll-toggle-btn'; button.textContent = getButtonText(); // 动态文字 button.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 99999; padding: 12px 16px; font-size: 14px; font-weight: bold; color: white; border: none; border-radius: 8px; cursor: pointer; box-shadow: 0 3px 8px rgba(0,0,0,0.2); transition: all 0.2s ease; `; updateButtonStyle(false); // 初始为红色 button.onclick = toggleScroll; button.onmouseenter = () => { if (!isScrolling) button.style.transform = 'scale(1.05)'; }; button.onmouseleave = () => { button.style.transform = 'scale(1)'; }; document.body.appendChild(button); } /** * 根据当前方向生成按钮文字 */ function getButtonText() { const directionText = scrollDirection === 'up' ? '上滑' : '下滑'; return `自动${directionText}:${isScrolling ? '开' : '关'}`; } /** * 更新按钮文字和颜色 */ function updateButtonUI() { const button = document.getElementById('tm-scroll-toggle-btn'); if (!button) return; button.textContent = getButtonText(); updateButtonStyle(isScrolling); } /** * 更新按钮背景色 */ function updateButtonStyle(running) { const button = document.getElementById('tm-scroll-toggle-btn'); if (!button) return; button.style.backgroundColor = running ? '#4CAF50' : '#f44336'; } /** * 切换滚动状态 */ function toggleScroll() { isScrolling = !isScrolling; updateButtonUI(); if (isScrolling) { smoothScroll(); } } /** * 平滑滚动主函数 */ function smoothScroll() { if (!isScrolling) return; const currentScroll = window.pageYOffset; const windowHeight = window.innerHeight; const documentHeight = document.documentElement.scrollHeight; const maxScroll = documentHeight - windowHeight; let canContinue = true; if (scrollDirection === 'down') { // 向下:检查是否到底 if (currentScroll >= maxScroll) { canContinue = false; } else { window.scrollBy(0, scrollStep); } } else if (scrollDirection === 'up') { // 向上:检查是否到顶 if (currentScroll <= 0) { canContinue = false; } else { window.scrollBy(0, -scrollStep); } } // 停止条件:到顶或到底 if (!canContinue) { isScrolling = false; updateButtonUI(); return; } // 继续滚动 setTimeout(smoothScroll, scrollInterval); } /** * 初始化入口 */ function init() { if (document.body) { createControls(); } else { document.addEventListener('DOMContentLoaded', createControls); } } // 快捷键 S:切换开关 document.addEventListener('keydown', (e) => { if (e.key.toLowerCase() === 's') { const btn = document.getElementById('tm-scroll-toggle-btn'); if (btn) btn.click(); } }); // 启动 init(); })();