使用上下键或WS键进行平滑滚动翻页,一次翻页0.9倍页面距离。键盘左右键或A/D键模拟点击页面中【上一页|上一章】【下一页|下一章】按钮,双击只点击【上一章】【下一章】按钮。可以与自动滚屏助手脚本联动。
// ==UserScript==
// @name 平滑滚动翻页
// @namespace http://tampermonkey.net/
// @version 2.2
// @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
// ==/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 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':
event.preventDefault();
handlePageNavigation('prev');
break;
case 'arrowright':
case 'd':
event.preventDefault();
handlePageNavigation('next');
break;
}
}
document.addEventListener('keydown', handleKeyEvents);
// 按键按下事件
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 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);
})();