// ==UserScript== // @name 高级自动滚动控制器 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 支持调节滚动速度、方向、底部行为,且面板可最小化的自动滚动工具 // @author yangwenren // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; // 全局变量 let isScrolling = false; let scrollSpeed = 5; // 滚动速度 let scrollDirection = 'down';// 滚动方向 (down/up) let bottomJump = true; // 底部是否跳转顶部 let panelMinimized = false; // 面板是否最小化 let scrollInterval; const MIN_SPEED = 1; const MAX_SPEED = 20; // 创建控制界面 function createControlPanel() { // 主面板容器 const panel = document.createElement('div'); panel.id = 'scrollControlPanel'; panel.style.cssText = ` position: fixed; bottom: 20px; right: 20px; background: rgba(255,255,255,0.95); border: 1px solid #ccc; border-radius: 8px; box-shadow: 0 2px 15px rgba(0,0,0,0.2); z-index: 999999; font-family: Arial, sans-serif; width: 250px; transition: all 0.3s ease; `; // 标题栏(包含最小化按钮) const titleBar = document.createElement('div'); titleBar.style.cssText = ` padding: 8px 15px; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; cursor: move; `; const title = document.createElement('h3'); title.textContent = '高级滚动控制器'; title.style.cssText = 'margin: 0; font-size: 15px;'; const minBtn = document.createElement('button'); minBtn.textContent = '−'; minBtn.style.cssText = ` width: 24px; height: 24px; border: none; background: transparent; font-size: 18px; cursor: pointer; line-height: 1; padding: 0; color: #666; `; minBtn.addEventListener('click', toggleMinimize); titleBar.append(title, minBtn); panel.appendChild(titleBar); // 内容区域(可折叠) const contentArea = document.createElement('div'); contentArea.id = 'panelContent'; contentArea.style.padding = '15px'; // 速度控制 const speedDiv = document.createElement('div'); speedDiv.style.marginBottom = '12px'; const speedLabel = document.createElement('label'); speedLabel.textContent = `滚动速度: ${scrollSpeed}`; speedLabel.id = 'speedLabel'; speedLabel.style.display = 'block'; speedLabel.style.marginBottom = '5px'; const speedSlider = document.createElement('input'); speedSlider.type = 'range'; speedSlider.min = MIN_SPEED; speedSlider.max = MAX_SPEED; speedSlider.value = scrollSpeed; speedSlider.style.width = '100%'; speedSlider.addEventListener('input', function() { scrollSpeed = parseInt(this.value); document.getElementById('speedLabel').textContent = `滚动速度: ${scrollSpeed}`; if (isScrolling) updateScrollInterval(); }); speedDiv.append(speedLabel, speedSlider); contentArea.appendChild(speedDiv); // 方向控制 const directionDiv = document.createElement('div'); directionDiv.style.marginBottom = '12px'; directionDiv.style.display = 'flex'; directionDiv.style.alignItems = 'center'; directionDiv.style.gap = '10px'; const directionLabel = document.createElement('label'); directionLabel.textContent = '滚动方向:'; directionLabel.style.width = '80px'; const directionSelect = document.createElement('select'); directionSelect.style.flex = '1'; directionSelect.innerHTML = ` `; directionSelect.value = scrollDirection; directionSelect.addEventListener('change', function() { scrollDirection = this.value; if (isScrolling) updateScrollInterval(); }); directionDiv.append(directionLabel, directionSelect); contentArea.appendChild(directionDiv); // 底部跳转控制 const jumpDiv = document.createElement('div'); jumpDiv.style.marginBottom = '15px'; jumpDiv.style.display = 'flex'; jumpDiv.style.alignItems = 'center'; jumpDiv.style.gap = '10px'; const jumpLabel = document.createElement('label'); jumpLabel.textContent = '底部行为:'; jumpLabel.style.width = '80px'; const jumpSelect = document.createElement('select'); jumpSelect.style.flex = '1'; jumpSelect.innerHTML = ` `; jumpSelect.value = bottomJump ? 'jump' : 'reverse'; jumpSelect.addEventListener('change', function() { bottomJump = this.value === 'jump'; if (isScrolling) updateScrollInterval(); }); jumpDiv.append(jumpLabel, jumpSelect); contentArea.appendChild(jumpDiv); // 控制按钮 const buttonDiv = document.createElement('div'); buttonDiv.style.display = 'flex'; buttonDiv.style.gap = '8px'; const startBtn = document.createElement('button'); startBtn.textContent = '开始滚动'; startBtn.style.cssText = ` flex: 1; padding: 6px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; `; const stopBtn = document.createElement('button'); stopBtn.textContent = '停止滚动'; stopBtn.style.cssText = ` flex: 1; padding: 6px; background: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer; `; stopBtn.disabled = true; startBtn.addEventListener('click', () => { if (!isScrolling) { startScrolling(); isScrolling = true; startBtn.disabled = true; stopBtn.disabled = false; } }); stopBtn.addEventListener('click', () => { if (isScrolling) { clearInterval(scrollInterval); isScrolling = false; startBtn.disabled = false; stopBtn.disabled = true; } }); buttonDiv.append(startBtn, stopBtn); contentArea.appendChild(buttonDiv); panel.appendChild(contentArea); document.body.appendChild(panel); // 支持面板拖动 makePanelDraggable(panel, titleBar); } // 切换最小化/展开状态 function toggleMinimize() { const panel = document.getElementById('scrollControlPanel'); const content = document.getElementById('panelContent'); const minBtn = panel.querySelector('button'); panelMinimized = !panelMinimized; if (panelMinimized) { // 最小化状态 content.style.display = 'none'; panel.style.width = 'auto'; minBtn.textContent = '+'; } else { // 展开状态 content.style.display = 'block'; panel.style.width = '250px'; minBtn.textContent = '−'; } } // 使面板可拖动 function makePanelDraggable(panel, handle) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; handle.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // 获取鼠标初始位置 pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; // 当鼠标移动时调用elementDrag函数 document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // 计算新的位置 pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // 设置元素新的位置 panel.style.top = (panel.offsetTop - pos2) + "px"; panel.style.left = (panel.offsetLeft - pos1) + "px"; // 清除bottom和right属性,避免冲突 panel.style.bottom = "auto"; panel.style.right = "auto"; } function closeDragElement() { // 停止移动 document.onmouseup = null; document.onmousemove = null; } } // 更新滚动间隔(参数变化时调用) function updateScrollInterval() { clearInterval(scrollInterval); startScrolling(); } // 滚动逻辑实现 function startScrolling() { scrollInterval = setInterval(() => { const currentPos = window.scrollY; const windowHeight = window.innerHeight; const docHeight = Math.max( document.body.scrollHeight, document.body.offsetHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight ); // 计算边界 const atBottom = currentPos + windowHeight >= docHeight - 50; const atTop = currentPos <= 50; let newPos; // 根据方向计算新位置 if (scrollDirection === 'down') { newPos = currentPos + scrollSpeed; // 处理底部逻辑 if (atBottom) { if (bottomJump) { newPos = 0; // 跳转到顶部 } else { scrollDirection = 'up'; // 反向滚动 newPos = currentPos - scrollSpeed; } } } else { // 向上滚动 newPos = currentPos - scrollSpeed; // 处理顶部逻辑 if (atTop) { if (bottomJump) { newPos = docHeight - windowHeight; // 跳转到底部 } else { scrollDirection = 'down'; // 反向滚动 newPos = currentPos + scrollSpeed; } } } window.scrollTo(0, newPos); }, 20); } // 初始化 createControlPanel(); })();