Greasy Fork is available in English.
滚轮触底后二次滚动加载,添加回到顶部按钮
// ==UserScript==// @name NGA自动翻页// @namespace http://tampermonkey.net/// @version 1.0// @license MIT// @description 滚轮触底后二次滚动加载,添加回到顶部按钮// @author NoWorld// @match *://bbs.nga.cn/*// @match *://ngabbs.com/*// @grant none// @icon https://img3.nga.cn/favicon.ico// ==/UserScript==(function() {'use strict';// ====================== 自动翻页功能 ======================// 配置参数const SCROLL_THRESHOLD = 50; // 触底阈值(px)const COOLDOWN_TIME = 800; // 操作冷却时间(ms)let lastLoadTime = 0; // 最后加载时间戳let hasReachedBottom = false; // 首次触底状态// 精准触底检测function isAtBottom() {return window.scrollY + window.innerHeight >=document.documentElement.scrollHeight - SCROLL_THRESHOLD;}// 改进版滚轮方向检测function handleWheel(e) {// 冷却期拦截if (Date.now() - lastLoadTime < COOLDOWN_TIME) return;// 方向检测 (兼容所有浏览器)const delta = Math.sign(e.deltaY || // Chrome/Firefox(e.wheelDelta ? -e.wheelDelta/120 : 0) || // IE(e.detail ? e.detail : 0) // Old Firefox);// 仅处理向下滚动if (delta <= 0) return;// 核心逻辑if (isAtBottom()) {if (!hasReachedBottom) {// 首次触底:只记录状态hasReachedBottom = true;// console.log('[状态] 首次滚轮触底');} else {// 二次触底:触发加载// console.log('[动作] 二次滚轮触底 → 加载');loadNextPage();hasReachedBottom = false;lastLoadTime = Date.now();}} else {// 不在底部时重置状态hasReachedBottom = false;}}// 加载下一页function loadNextPage() {const btn = document.querySelector('a.uitxt1[title="加载下一页"]');if (btn?.offsetParent) {btn.click();btn.style.opacity = '0.5'; // 视觉反馈代替直接隐藏setTimeout(() => btn.style.opacity = '', 1000);}}// 高性能事件监听(被动模式+防抖)let wheelTimeout;const wheelHandler = (e) => {clearTimeout(wheelTimeout);wheelTimeout = setTimeout(() => handleWheel(e), 50);};window.addEventListener('wheel', wheelHandler, { passive: true });window.addEventListener('DOMMouseScroll', wheelHandler, { passive: true }); // Firefox// 初始加载检测setTimeout(() => isAtBottom() && loadNextPage(), 2000);// ====================== 返回顶部按钮 ======================const backToTopBtn = document.createElement('button');backToTopBtn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true"class="Zi Zi--BackToTop" fill="#FFF0CD"><path fill-rule="evenodd"d="M13.204 3.107a1.75 1.75 0 0 0-2.408 0L3.806 9.73c-1.148 1.088-.378 3.02 1.204 3.02h2.24V20c0 .966.784 1.75 1.75 1.75h6A1.75 1.75 0 0 0 16.75 20v-7.25h2.24c1.582 0 2.353-1.932 1.204-3.02l-6.99-6.623Z"clip-rule="evenodd"></path></svg>`;// 基础样式Object.assign(backToTopBtn.style, {position: 'fixed',bottom: '80px',right: '20px',width: '40px',height: '40px',borderRadius: '50%',background: '#591804',border: 'none',boxShadow: '0 4px 12px rgba(0,0,0,0.2)',cursor: 'pointer',opacity: '0',transform: 'translateY(20px) scale(1)',transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',zIndex: '9999',display: 'flex',alignItems: 'center',justifyContent: 'center',pointerEvents: 'none'});// 悬停特效backToTopBtn.addEventListener('mouseenter', () => {backToTopBtn.style.background = '#7a2b0a';backToTopBtn.style.transform = 'translateY(0) scale(1.1)';backToTopBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.3)';});backToTopBtn.addEventListener('mouseleave', () => {backToTopBtn.style.background = '#591804';backToTopBtn.style.transform = 'translateY(0) scale(1)';backToTopBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';});// 显示控制let lastScrollY = 0;const checkScrollPosition = () => {const show = window.scrollY > 300;backToTopBtn.style.opacity = show ? '1' : '0';backToTopBtn.style.pointerEvents = show ? 'auto' : 'none';};window.addEventListener('scroll', () => {requestAnimationFrame(checkScrollPosition);});// 点击功能backToTopBtn.addEventListener('click', () => {window.scrollTo({ top: 0, behavior: 'smooth' });});document.body.appendChild(backToTopBtn);checkScrollPosition();})();