2026-03-25 20:22:48
通过JavaScript的History API可实现无刷新导航,核心方法包括pushState添加历史记录、replaceState修改当前记录,并监听popstate事件响应浏览器操作,结合AJAX加载内容与路由拦截构建单页应用(SPA)的平滑切换体验。
一、History API核心方法pushState(state, title, url)
功能:向浏览器历史栈添加新记录,更新URL但不刷新页面。
参数:
state:对象,存储与状态关联的数据(如页面数据),可通过popstate事件获取。
title:当前浏览器大多忽略,可传空字符串。
url:新URL(必须同源,否则报错)。
示例:history.pushState({page: 'home'}, '', '/home');执行后地址栏变为/home,页面未刷新,后续可通过popstate获取state对象。
replaceState(state, title, url)
功能:替换当前历史记录,不新增条目(如动态更新搜索参数)。
示例:history.replaceState({query: 'hello'}, '', '?q=hello');修改当前URL为?q=hello,但历史栈长度不变,点击后退仍返回上一有效页面。
仅通过pushState或replaceState添加的记录携带state对象,直接刷新或访问页面时state为null。
拦截链接点击事件
阻止默认跳转行为,通过AJax加载内容并更新历史记录。
示例:document.querySelectorAll('a').forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const url = this.getAttribute('href'); fetchContent(url).then(data => { displayContent(data); // 渲染新内容 history.pushState({url, data}, '', url); // 更新历史记录 }); });});
处理popstate事件
根据event.state恢复页面状态(如从缓存读取或重新请求数据)。
示例:window.addEventListener('popstate', function(event) { if (event.state) { // 从state中获取数据并渲染 displayContent(event.state.data); } else { // 处理无state的情况(如加载初始页面) fetch('/initial-page').then(response => response.text()).then(html => { document.body.innerHTML = html; }); }});
服务端路由Fallback
问题:用户直接刷新或访问非入口URL时,服务端需返回SPA的HTML(如index.html),避免404。
解决方案:
配置服务端(如Nginx、Express)将所有路由指向index.html。
在客户端根据URL动态加载内容(如通过window.location.pathname判断路由)。
缓存已加载内容,避免重复请求。
使用requestAnimationFrame或IntersectionObserver优化渲染性能。
通过合理使用History API,结合AJax加载与路由拦截,可构建高效、流畅的无刷新导航体验,显著提升用户交互感知。