需要注意这些点:
位置记录: 监听滚动事件,记录滚动位置 存储介质: 使用浏览器存储方案持久化数据 位置恢复: 页面加载时读取存储数据并定位
方案1:滚动监听 + localStorage
// 记录滚动位置 window.addEventListener('scroll', throttle(function() { const scrollY = window.scrollY || document.documentElement.scrollTop; localStorage.setItem('lastScrollPosition', scrollY); }, 100)); // 节流函数降低性能消耗 // 恢复位置 window.addEventListener('DOMContentLoaded', () => { const savedPosition = localStorage.getItem('lastScrollPosition'); if (savedPosition) { window.scrollTo(0, parseInt(savedPosition)); } }); // 节流函数实现 function throttle(fn, delay) { let lastCall = 0; returnfunction(...args) { const now = Date.now(); if (now - lastCall < delay) return; lastCall = now; return fn.apply(this, args); }; }
方案2:锚点标记 + URL参数
// 记录锚点元素ID document.querySelectorAll('.section').forEach(el => { el.addEventListener('click', () => { const activeId = el.id; history.replaceState(null, '', `#${activeId}`); }); }); // 恢复滚动 window.addEventListener('load', () => { const hash = window.location.hash.slice(1); if (hash) { const target = document.getElementById(hash); target?.scrollIntoView({ behavior: 'smooth' }); } });
方案3:Intersection Observer API
// 记录最近可见的元素 const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { const elementId = entry.target.id; localStorage.setItem('lastVisibleElement', elementId); } }); }, { threshold: 0.5 }); // 观察所有章节元素 document.querySelectorAll('.chapter').forEach(el => observer.observe(el)); // 恢复时滚动到最近可见元素 const lastElementId = localStorage.getItem('lastVisibleElement'); if (lastElementId) { document.getElementById(lastElementId)?.scrollIntoView(); }
方案4:滚动位置预测(适用于动态加载内容)
let lastKnownPos = 0; let ticking = false; window.addEventListener('scroll', () => { lastKnownPos = window.scrollY; if (!ticking) { window.requestAnimationFrame(() => { // 预测用户滚动方向 const viewportHeight = window.innerHeight; const predictPosition = lastKnownPos + (viewportHeight * 0.3); localStorage.setItem('predictPos', predictPosition); ticking = false; }); ticking = true; } }); // 恢复时使用预测位置 const savedPos = localStorage.getItem('predictPos'); if (savedPos) { window.scrollTo(0, savedPos); }