// ==UserScript== // @name 平滑滚动翻页 // @namespace http://tampermonkey.net/ // @version 2.1 // @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 https://update.greasyfork.icu/scripts/497164/%E5%B9%B3%E6%BB%91%E6%BB%9A%E5%8A%A8%E7%BF%BB%E9%A1%B5.user.js // @updateURL https://update.greasyfork.icu/scripts/497164/%E5%B9%B3%E6%BB%91%E6%BB%9A%E5%8A%A8%E7%BF%BB%E9%A1%B5.meta.js // ==/UserScript== (function() { 'use strict'; // 状态变量 let isScrollKeyPressed = false; let autoScrollWasActive = false; let lastKeyPressTime = 0; let clickTimer = null; let scrollDistance = window.innerHeight * 0.9; // 默认滚动距离 // 检查自动滚动接口 const isAutoScrollAvailable = () => typeof window.getAutoScrollState === 'function'; // 检测页面按钮 function hasNextPageButton() { return simulateClickByText('下一页') || simulateClickByText('下一页>'); } function hasLastPageButton() { return simulateClickByText('上一页') || simulateClickByText('上一页>'); } // 模拟点击函数 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 handlePageNavigation(direction) { if (clickTimer == null) { clickTimer = setTimeout(() => { const isPrev = direction === 'prev'; if (isPrev ? hasLastPageButton() : hasNextPageButton()) { if (isPrev) { simulateClickByText('上一页') || simulateClickByText('<上一页'); } else { simulateClickByText('下一页') || simulateClickByText('下一页>'); } } else { simulateClickByText(isPrev ? '上一章' : '下一章'); } document.body.focus(); clickTimer = null; }, 300); } else { clearTimeout(clickTimer); clickTimer = null; 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; // 暂停自动滚动 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' }); } } } // 统一按键处理 function handleKeyEvents(e) { if (event.ctrlKey || event.altKey || event.shiftKey) return; // 忽略输入框中的按键 if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') { return; } switch(e.key.toLowerCase()) { case 'arrowleft': case 'a': handlePageNavigation('prev'); break; case 'arrowright': case 'd': handlePageNavigation('next'); break; } } document.addEventListener('keydown', handleKeyEvents); // 按键释放事件 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); })();