在 bootstrap 5 的 masonry 布局中,因元素动态重排导致原生滚动位置恢复失效;需确保滚动恢复逻辑在 masonry 完全渲染后执行,而非仅依赖 window.onload。
Bootstrap 5 官方 Masonry 示例(基于 CSS column-count + break-inside: avoid)本身不触发重排回调,因此 window.onload 触发时,Masonry 的列高计算可能尚未完成——此时调用 window.scrollTo(0, scrollpos) 会因页面实际高度未稳定而失效(尤其在内容异步加载或字体加载延迟时更明显)。
✅ 正确做法是:将滚动恢复延迟至 DOM 渲染与布局稳定之后执行。推荐使用 requestAnimationFrame 双帧策略,确保 Masonry 列已正确分列:
// ✅ 推荐:等待两帧,确保 Masonry 布局完成
window.addEventListener('load', () => {
const scrollpos = sessionStorage.getItem('scrollpos');
if (scrollpos) {
// 第一帧:让浏览器完成初始渲染
requestAnimationFrame(() => {
// 第二帧:确保 Masonry 列高已计算完毕
requestAnimationFrame(() => {
window.scrollTo(0, parseInt(scrollpos, 10));
});
});
}
});
// ✅ 持久化滚动位置(兼容所有卸载场景)
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('scrollpos', window.scrollY.toString());
});⚠️ 注意事项:
dow.onbeforeunload —— 使用 addEventListener 更安全,允许多个监听器共存;总结:window.onload 并不等于“布局就绪”,Masonry 的视觉重排依赖 CSS 列模型的最终计算。通过 requestAnimationFrame 延迟滚动恢复,是兼顾兼容性与可靠性的最小改动方案。