用戶在列表頁(如商品列表)瀏覽到第 20 項,點擊進入詳情頁,返回時希望自動定位回原來的滾動位置,而不是重新加載頁面頂部。這類似於淘寶、京東等電商網站的體驗。
根據頁面數據加載方式,主要有兩類解決方案:
如果列表頁是由後端直接渲染完整 HTML 返回,瀏覽器歷史記錄中保存了完整的頁面狀態(包含滾動位置)。此時只需使用 JavaScript 歷史 API:
<!-- 詳情頁返回按鈕 -->
<button onclick="history.back()">返回列表</button>
<!-- 或指定步數 -->
<button onclick="history.go(-1)">返回上一頁</button>
優點:零代碼改動,瀏覽器原生支持恢復滾動位置(現代瀏覽器均支持)。
缺點:若列表頁使用 AJAX 分頁/無限滾動,歷史記錄中只有初始頁面,無法恢復動態加載的內容位置。
當列表數據通過 AJAX 分頁或無限滾動加載時,必須手動管理狀態:
sessionStorage 或 URL 參數。scrollTop。// 列表頁:離開前保存
window.addEventListener('beforeunload', () => {
const state = {
page: currentPage,
scrollY: window.scrollY,
filters: getCurrentFilters()
};
sessionStorage.setItem('listState', JSON.stringify(state));
});
// 列表頁:初始化時恢復
window.addEventListener('load', () => {
const saved = sessionStorage.getItem('listState');
if (saved) {
const state = JSON.parse(saved);
currentPage = state.page;
loadListData(state.page, () => {
window.scrollTo(0, state.scrollY);
});
applyFilters(state.filters);
sessionStorage.removeItem('listState'); // 清理
}
});
將分頁、篩選、滾動位置編碼到 URL Hash 或 Query String 中:
// 跳轉詳情頁時
location.href = `/detail/${itemId}?returnUrl=${encodeURIComponent(location.href)}`;
// 詳情頁返回按鈕
<a href="javascript:history.back()">返回</a>
// 或讀取 returnUrl 參數跳轉
列表頁解析 URL 參數恢復狀態,這樣用戶刷新頁面或分享鏈接也能保持狀態。
| 場景 | 推薦方案 |
|---|---|
| 傳統服務端渲染分頁 | history.back() 原生支持 |
| AJAX 分頁/無限滾動 | sessionStorage + 滾動恢復 |
| 需要可分享/可刷新狀態 | URL 狀態化 (History API pushState) |
| 複雜篩選+排序+分頁 | URL 狀態化 + 服務端渲染首屏 |
「返回並保持位置」的本質是狀態管理。靜態頁面依賴瀏覽器原生歷史機制;動態頁面需開發者顯式保存/恢復滾動位置、分頁狀態及篩選條件。選擇方案時請優先考慮用戶體驗(可刷新、可分享)與實現成本的平衡。