// ==UserScript== // @name 阅读位置记忆 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 自动保存和恢复阅读位置,无任何UI提示,支持移动端特性适配 // @author You // @match *://*/* // @grant none // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/573657/%E9%98%85%E8%AF%BB%E4%BD%8D%E7%BD%AE%E8%AE%B0%E5%BF%86.user.js // @updateURL https://update.greasyfork.icu/scripts/573657/%E9%98%85%E8%AF%BB%E4%BD%8D%E7%BD%AE%E8%AE%B0%E5%BF%86.meta.js // ==/UserScript== (function() { 'use strict'; // 生成当前页面的唯一标识 (保留 search 参数以区分分页,去除 hash 防止页内跳转干扰) const pageKey = 'read_pos_' + window.location.origin + window.location.pathname + window.location.search; // 核心逻辑:恢复阅读位置 function restorePosition() { const savedPos = localStorage.getItem(pageKey); if (savedPos !== null) { const pos = parseFloat(savedPos); if (pos > 0) { // 首次尝试滚动 window.scrollTo(0, pos); // 延迟 500ms 再次强制校准,应对移动端图片延迟加载或动态渲染导致的页面高度突变 setTimeout(() => window.scrollTo(0, pos), 500); } } } // 核心逻辑:防抖保存当前位置 let scrollTimeout; function savePosition() { if (scrollTimeout) { clearTimeout(scrollTimeout); } scrollTimeout = setTimeout(() => { const currentPos = window.scrollY || document.documentElement.scrollTop; localStorage.setItem(pageKey, currentPos); }, 500); // 停止滚动 500ms 后才执行存储,节省性能 } // 绑定滚动事件监听(passive: true 提升移动端滚动流畅度) window.addEventListener('scroll', savePosition, { passive: true }); // 页面加载时的执行逻辑 if (document.readyState === 'complete' || document.readyState === 'interactive') { restorePosition(); } else { window.addEventListener('DOMContentLoaded', restorePosition); // 保底:确保所有资源加载完毕后再执行一次 window.addEventListener('load', restorePosition); } })();