您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
滚动到顶/底、滚动条-新、记录页面滚动、屏幕常亮和自动滚动
// ==UserScript== // @name 网页随心滚 // @namespace http://tampermonkey.net/ // @version 2.0 // @description 滚动到顶/底、滚动条-新、记录页面滚动、屏幕常亮和自动滚动 // @author ^o^ // @match *://*/* // @grant GM_registerMenuCommand // @run-at document-start // ==/UserScript== (function() { 'use strict'; let w = window, d = document; let eScrollBtn = true, eScrollBar = true, eWakeLock = true; let scrollBarPosition = localStorage.getItem('scrollBarPosition') || 'right'; // 'left' or 'right' let scrollBtnPosition = localStorage.getItem('scrollBtnPosition') || 'right'; // 'left' or 'right' // 注册菜单命令 GM_registerMenuCommand('滚动到顶/底按钮:开/关', toggleScrollBtn); GM_registerMenuCommand('滚动条:开/关', toggleScrollBar); GM_registerMenuCommand('滚动条位置:左/右切换', toggleScrollBarPosition); GM_registerMenuCommand('滚动到顶/底按钮位置:左/右切换', toggleScrollBtnPosition); GM_registerMenuCommand('保持屏幕常亮:开/关', toggleWakeLock); function toggleScrollBtn() { eScrollBtn = !eScrollBtn; let b = d.getElementById('scroll-top-btn'); if (b) b.remove(); if (eScrollBtn) initScrollBtn(); } function toggleScrollBar() { eScrollBar = !eScrollBar; let s = d.getElementById('theScrollBar'); if (s) s.remove(); if (eScrollBar) initScrollBar(); } function toggleWakeLock() { eWakeLock = !eWakeLock; if (eWakeLock) requestWL(); else if (wakeLock) wakeLock.release(); } function toggleScrollBarPosition() { scrollBarPosition = scrollBarPosition === 'left' ? 'right' : 'left'; localStorage.setItem('scrollBarPosition', scrollBarPosition); let s = d.getElementById('theScrollBar'); if (s) { if (scrollBarPosition === 'right') { s.style.right = '2vw'; s.style.left = 'auto'; } else { s.style.left = '2vw'; s.style.right = 'auto'; } } } function toggleScrollBtnPosition() { scrollBtnPosition = scrollBtnPosition === 'left' ? 'right' : 'left'; localStorage.setItem('scrollBtnPosition', scrollBtnPosition); let b = d.getElementById('scroll-top-btn'); if (b) { b.style.left = scrollBtnPosition === 'left' ? '15px' : ''; b.style.right = scrollBtnPosition === 'right' ? '15px' : ''; } } function initScrollBtn() { let b = d.createElement('button'); b.textContent = '▲'; b.id = 'scroll-top-btn'; Object.assign(b.style, { position: 'fixed', bottom: '15%', zIndex: 999999, width: '35px', height: '35px', borderRadius: '50%', padding: 0, background: 'rgba(255,255,255,0.3)', backdropFilter: 'blur(5px)', display: 'none', fontSize: '16px', textAlign: 'center', lineHeight: '35px', fontWeight: 'bold', cursor: 'pointer', transition: 'all 0.3s ease', border: 'none' }); // 根据位置设置 left 或 right if (scrollBtnPosition === 'left') { b.style.left = '13px'; } else { b.style.right = '13px'; } d.body.appendChild(b); let lastY = w.pageYOffset, t; w.addEventListener('scroll', () => { b.textContent = w.scrollY > lastY ? '▼' : '▲'; lastY = w.scrollY; b.style.display = w.pageYOffset > 100 ? 'block' : 'none'; clearTimeout(t); t = setTimeout(() => b.style.display = 'none', 2000); }); b.addEventListener('mouseenter', () => { b.style.background = 'rgba(255,255,255,0.6)'; b.style.transform = 'scale(1.1)'; }); b.addEventListener('mouseleave', () => { b.style.background = 'rgba(255,255,255,0.3)'; b.style.transform = 'scale(1)'; }); b.addEventListener('click', () => w.scrollTo({ top: b.textContent === '▲' ? 0 : d.documentElement.scrollHeight, behavior: 'smooth' })); } function initScrollBar() { // 创建滚动条 DOM 元素 const theScrollBar = document.createElement("div"); // 设置滚动条的 ID 和文本 theScrollBar.id = "theScrollBar"; theScrollBar.innerHTML = "▲<br>▼"; // 设置滚动条样式 theScrollBar.setAttribute( "style", "font-size:2.6vw ;width:6vw ;line-height:5vw ;display: block;text-align:center ;background-color:rgba(255,255,255) ;opacity: 0 ;box-shadow:0px 1px 5px rgba(0,0,0,0.2) ;color:#000 ;position:fixed ;top: -14vw;right:-10vw ;z-index:9999999 ;transition: opacity 0.4s ease-in-out,right 0.4s; border-radius:3vw " ); // 根据位置设置 left 或 right if (scrollBarPosition === 'left') { theScrollBar.style.left = '2vw'; theScrollBar.style.right = 'auto'; } else { theScrollBar.style.right = '-10vw'; theScrollBar.style.left = 'auto'; } // 将滚动条元素添加到页面中 document.body.appendChild(theScrollBar); // 存储网页高度和上次滚动位置 let webHeight = null; let lastScrollTop = null; // 更新滚动条位置的函数 function updateScrollBar() { // 获取当前的滚动位置 const scrollTop = window.scrollY; // 如果滚动位置改变了,重新计算滚动条位置 if (scrollTop !== lastScrollTop) { const scrollBarTop = (scrollTop / webHeight) * (window.innerHeight - theScrollBar.clientHeight); if (scrollBarTop < 0) { theScrollBar.style.top = "0"; } else if (scrollBarTop + theScrollBar.clientHeight > window.innerHeight) { theScrollBar.style.top = `${window.innerHeight - theScrollBar.clientHeight}px`; webHeight = document.documentElement.scrollHeight - window.innerHeight; } else { theScrollBar.style.top = `${scrollBarTop}px`; } lastScrollTop = scrollTop; } // 使用 requestAnimationFrame 函数,优化渲染性能 window.requestAnimationFrame(updateScrollBar); } // 添加 touchstart 事件监听器,当用户在手机上开始触摸屏幕时触发 window.addEventListener("touchstart", function() { //如果网页高度过低,不需要添加滚动条 if (document.documentElement.scrollHeight <= window.innerHeight * 2) { return; } // 获取网页高度,并开始更新滚动条位置 webHeight = document.documentElement.scrollHeight - window.innerHeight; updateScrollBar(); }); // 定义一些与触摸事件相关的变量 let startOffset = null; // 滚动条开始滚动时触发的函数 function startScroll(event) { event.preventDefault(); event.stopPropagation(); startOffset = event.changedTouches[0].clientY - parseInt(theScrollBar.style.top); } // 滚动条正在滚动时触发的函数 function scrolling(event) { event.preventDefault(); event.stopPropagation(); // 计算当前滚动条的位置和滑动距离,并更新滚动位置和滚动条位置 const currentY = event.changedTouches[0].clientY; const scrollBarTop = currentY - startOffset; if (scrollBarTop < 0) { theScrollBar.style.top = "0px"; } else if (scrollBarTop > window.innerHeight - theScrollBar.clientHeight) { theScrollBar.style.top = `${window.innerHeight - theScrollBar.clientHeight}px`; } else { theScrollBar.style.top = `${scrollBarTop}px`; } const scrollTop = (scrollBarTop / (window.innerHeight - theScrollBar.clientHeight)) * webHeight; window.scrollTo(window.scrollX, scrollTop); } // 为滚动条添加触摸事件监听器 theScrollBar.addEventListener("touchstart", startScroll, { passive: false }); theScrollBar.addEventListener("touchmove", scrolling, { passive: false }); // 停止滚动1秒后隐藏 let timer; window.addEventListener("scroll", function() { clearTimeout(timer); if (scrollBarPosition === 'right') { theScrollBar.style.right = "2vw"; theScrollBar.style.left = "auto"; } else { theScrollBar.style.left = "2vw"; theScrollBar.style.right = "auto"; } theScrollBar.style.opacity = "0.8"; timer = setTimeout(() => { if (scrollBarPosition === 'right') { theScrollBar.style.right = "-10vw"; theScrollBar.style.left = "auto"; } else { theScrollBar.style.left = "-10vw"; theScrollBar.style.right = "auto"; } theScrollBar.style.opacity = "0"; }, 1000); }); // 定义触顶/底反弹动画的函数 function bounceAnimation() { // 获取当前滚动条的位置 const scrollTop = window.scrollY; // 获取滚动条的高度 const scrollBarHeight = theScrollBar.clientHeight; // 获取滚动速度 const scrollSpeed = Math.abs(scrollTop - lastScrollTop); // 设置滚动速度阈值 const threshold = 7; // 如果滚动条触顶,且滚动速度超过阈值,执行反弹动画 if (scrollTop === 0 && scrollSpeed > threshold) { theScrollBar.style.animation = "bounce-down 0.4s"; setTimeout(() => { theScrollBar.style.animation = ""; }, 500); } // 如果滚动条触底,且滚动速度超过阈值,执行反弹动画 if (scrollTop + window.innerHeight >= document.documentElement.scrollHeight && scrollSpeed > threshold) { theScrollBar.style.animation = "bounce-up 0.4s"; setTimeout(() => { theScrollBar.style.animation = ""; }, 500); } } // 添加触顶/底反弹动画的事件监听器 window.addEventListener("scroll", bounceAnimation); // CSS样式 const styles = ` @keyframes bounce-down { 0% { transform: translateY(0); } 30% { transform: translateY(10px); } 100% { transform: translateY(0); } } @keyframes bounce-up { 0% { transform: translateY(0); } 30% { transform: translateY(-10px); } 100% { transform: translateY(0); } } `; // 创建样式元素并将样式添加到头部 const styleElement = document.createElement("style"); styleElement.innerHTML = styles; document.head.appendChild(styleElement); } let wakeLock = null; async function requestWL() { if (!('wakeLock' in navigator)) return; try { wakeLock = await navigator.wakeLock.request("screen"); } catch (e) {} } eWakeLock && requestWL(); let scrolling = false, interval, speed = 25, pixels = 1; function toggleAutoScroll() { if (scrolling) { scrolling = false; clearInterval(interval); } else { scrolling = true; interval = setInterval(() => { w.scrollBy(0, pixels); if (w.innerHeight + w.scrollY >= d.body.scrollHeight) { w.scrollBy(0, 1); } }, speed); } } GM_registerMenuCommand('自动滚动:开始/停止', toggleAutoScroll); GM_registerMenuCommand('自动滚动:配置参数', () => { let s = prompt('滚动间隔(ms):', speed); if (s !== null) speed = parseInt(s) || speed; let p = prompt('每次滚动像素(px):', pixels); if (p !== null) pixels = parseInt(p) || pixels; }); eScrollBtn && initScrollBtn(); eScrollBar && initScrollBar(); // 记录页面滚动位置 w.addEventListener('scroll', () => { localStorage.setItem('pageScrollPosition', JSON.stringify({ top: w.scrollY, left: w.scrollX })); }); // 页面加载时恢复滚动位置 w.addEventListener('load', () => { let position = localStorage.getItem('pageScrollPosition'); if (position) { let scrollPosition = JSON.parse(position); w.scrollTo(scrollPosition.left, scrollPosition.top); } }); })();