Greasy Fork is available in English.
自动保存和恢复阅读位置,无任何UI提示,支持移动端特性适配
// ==UserScript==
// @name 阅读位置记忆
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 自动保存和恢复阅读位置,无任何UI提示,支持移动端特性适配
// @author You
// @match *://*/*
// @grant none
// @run-at document-end
// ==/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);
}
})();