// ==UserScript== // @name 平滑滚动翻页 // @namespace http://tampermonkey.net/ // @version 1.9 // @description 使用上下键或WS键进行平滑滚动翻页,一次翻页0.9倍页面距离。键盘左右键或A/D键模拟点击页面中【上一页|上一章】【下一页|下一章】按钮,双击只点击【上一章】【下一章】按钮。可以与自动滚屏助手脚本联动。 // @author coccvo // @include * // @exclude https://www.bilibili.com/* // @grant none // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAVdJREFUWEftlj1Ow0AQhd9YWKKmy3b8FPSpiKUojXMaKOAg0HAZCEUktB0HoMDu4twBkwxaLEvG7C7GzMoowvV437dvfnYIA3/k00+TgiX4Flo5df4BfuVABEx5yxuOSPtSFSQFRvxOq0cjPD9bTXwQ4gBN8frmPghRAJv4dxCCAPRCtH325Zs5OgX4pBkjCNBvKuwmAAMZgFvjSQQ6Z/Cxyx9xB8p4FC+X9NYUnM14Ly7XpQ1CFMAmXou6IMQACJTd69GnCm/fOE3WGcBHQbqAgasHrW58vTBPiksGrncTAEC+0MpZ7ebWaVLkAA6DOGAO9RXhePwUH+yr13aKxIqwPtgG4RI3/4gDVCCUE/hjEDFw0bY9WAr6vAaBHOiOIgjwB55j70IyXU1483U/FHSgst26kjnEg3XBoEtpXX6DruXdeyDYIOqOIF6E3aWryN4APxXqE/8OqY/0IehdmXQAAAAASUVORK5CYII= // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 状态变量 let isScrollKeyPressed = false; let autoScrollWasActive = false; let lastKeyPressTime = 0; const doublePressThreshold = 300; // 双击判定阈值(毫秒) let scrollDistance = window.innerHeight * 0.9; // 默认滚动距离 // 检查自动滚动接口 const isAutoScrollAvailable = () => typeof window.getAutoScrollState === 'function'; // 模拟点击函数 function simulateClickByText(textContent) { const links = document.querySelectorAll('a'); for (let i = 0; i < links.length; i++) { if (links[i].textContent.trim() === textContent) { links[i].click(); return true; } } return false; } // 分页按钮检测 function hasNextPageButton() { return simulateClickByText('下一页') || simulateClickByText('下一页>'); } function hasLastPageButton() { return simulateClickByText('上一页') || simulateClickByText('上一页>'); } // 处理单击分页 function handleSingleClick(direction) { const isPrev = direction === 'prev'; if (isPrev ? hasLastPageButton() : hasNextPageButton()) { if (isPrev) { simulateClickByText('上一页') || simulateClickByText('<上一页'); } else { simulateClickByText('下一页') || simulateClickByText('下一页>'); } } else { simulateClickByText(isPrev ? '上一章' : '下一章'); } document.body.focus(); } // 处理双击分页 function handleDoubleClick(direction) { simulateClickByText(direction === 'prev' ? '上一章' : '下一章'); document.body.focus(); } // 按键按下事件 function handleKeyDown(event) { const target = event.target; if ( target.tagName.toLowerCase() === 'input' || target.tagName.toLowerCase() === 'textarea' || target.isContentEditable || target.closest('[contenteditable="true"]') ) return; const key = event.key.toLowerCase(); const isScrollKey = ['w', 'arrowup', 's', 'arrowdown'].includes(key); if (isScrollKey) { isScrollKeyPressed = true; lastKeyPressTime = performance.now(); // 记录按键时间 // 暂停自动滚动 if (isAutoScrollAvailable() && window.getAutoScrollState()) { autoScrollWasActive = true; window.turnOffAutoScroll(); } // WS键单次滚动 if (key === 'w' || key === 'arrowup') { event.preventDefault(); window.scrollBy({ top: -scrollDistance, left: 0, behavior: 'smooth' }); } else if (key === 's' || key === 'arrowdown') { event.preventDefault(); window.scrollBy({ top: scrollDistance, left: 0, behavior: 'smooth' }); } } // AD键分页逻辑(保持不变) if (key === 'arrowleft' || key === 'a' || key === 'arrowright' || key === 'd') { const now = performance.now(); if (now - lastKeyPressTime < doublePressThreshold) { handleDoubleClick(key); } else { handleSingleClick(key); } lastKeyPressTime = now; } } // 按键释放事件 function handleKeyUp(event) { const key = event.key.toLowerCase(); const isScrollKey = ['w', 'arrowup', 's', 'arrowdown'].includes(key); if (isScrollKey) { isScrollKeyPressed = false; } // WS键释放后延迟恢复自动滚动 if (isScrollKey && autoScrollWasActive) { setTimeout(() => { if (!isScrollKeyPressed && isAutoScrollAvailable()) { window.startAutoScroll(); autoScrollWasActive = false; } }, 500); // 延迟500ms恢复 } } // 页面加载初始化 window.addEventListener('load', () => { scrollDistance = window.innerHeight * 0.9; // 动态计算滚动距离 }); // 窗口大小变化时更新滚动距离 window.addEventListener('resize', () => { scrollDistance = window.innerHeight * 0.9; }); // 添加事件监听 document.addEventListener('keydown', handleKeyDown); document.addEventListener('keyup', handleKeyUp); })();