阅读百分比 = (window.pageYOffset + window.innerHeight) / document.documentElement.scrollHeight × 100,四舍五入保留1位小数;以URL为键存取{percent, timestamp}对象,写入加防抖/节流,加载时优先按锚点ID滚动,失败再按百分比估算。

在HTML5中,用LocalStorage保存用户阅读进度和百分比,核心是监听滚动行为、计算当前可视区域占全文高度的比例,并持久化到本地存储。关键点在于:滚动时实时更新、页面加载时恢复、避免频繁写入影响性能。
如何计算阅读百分比
阅读百分比 = (窗口顶部距文档顶部距离 + 可视区高度) ÷ 文档总高度,结果乘以100并保留1位小数。注意使用document.documentElement.scrollHeight而非body.scrollHeight,避免因CSS重置导致高度取值异常。
- 推荐用
window.innerHeight和window.pageYOffset获取可视区高度和滚动偏移 - 为防小数精度误差,建议用
Math.round(percentage * 10) / 10四舍五入到0.1% - 若内容动态加载(如懒加载图片),需在内容渲染完成后重新计算,否则百分比可能失真
如何用LocalStorage存取进度
以当前页面URL为键名,存储对象{ percent: 82.5, timestamp: 1715623400 },便于后续扩展(如按时间判断是否过期)。读取时先检查是否存在,再解析JSON;写入前做防抖处理,避免每像素滚动都触发存储。
- 存:用
localStorage.setItem(key, JSON.stringify(data)) - 取:用
JSON.parse(localStorage.getItem(key) || '{}'),并校验percent是否为有效数字 - 建议加节流(如300ms内最多写1次),可用
setTimeout简单实现防抖
页面加载时自动滚动到上次位置
仅靠百分比无法精确还原滚动位置(因页面结构或字体加载可能导致高度变化),更稳妥的做法是:记录百分比的同时,也存一个相对锚点(如最近的
标题ID),加载后优先尝试滚动到该ID;若失败,再按百分比估算位置。
立即学习“前端免费学习笔记(深入)”;
- 滚动到ID:
document.getElementById(id)?.scrollIntoView({ behavior: 'auto' }) - 退而求其次按百分比滚动:
window.scrollTo(0, (percent / 100) * document.body.scrollHeight) - 为提升体验,可在
DOMContentLoaded后延迟100ms再执行恢复逻辑,避开样式未就绪阶段
兼容性与边界情况处理
LocalStorage在所有现代浏览器中支持良好,但需注意:私密模式下部分浏览器会抛出QuotaExceededError;iOS Safari在页面后台时可能暂停JS执行,导致最后几次滚动未保存。
- 写入前加
try...catch捕获异常,失败时降级为内存缓存(刷新即丢) - 对单页应用(SPA),需监听路由变化,在离开当前文章页前主动保存一次
- 用户手动拖动滚动条或用键盘翻页(PageDown)也会触发
scroll事件,无需额外监听



















