单页面应用中,单纯的url改变,网页不会重载,但页面会发生动态的变化,主要是通过下面两种方式来实现的:
- hash路由:监听浏览器地址hash值变化,改变网页内容;
- history路由:利用history API实现url地址改变,改变网页内容;
以下分别介绍两种路由模式。
1. history 路由
允许对浏览器的会话历史进行操作
1.1 属性
length: 返回会话历史中的数量,包括当前页面
scrollRestoration
state: 历史堆栈顶部的状态值
1.2 方法
forward
window.history.forward() —— 同浏览器的前进
back
window.history.back() —— 同浏览器的后退
go —— 跳转到历史中特定记录
- window.history.go(-1) 同 back,后退
- window.history.go(1) 同 forward,前进
- window.history.go(0) // 刷新当前页面
- window.history.go() // 刷新当前页面
pushState
添加一个值到浏览器的会话历史堆栈中,页面不会刷新,但地址栏会改变,history 堆栈也会改变,history.state 也会改变。
history.pushState(state, title [, url])
url 不可跨域,否则会报错
replaceState
修改 history 对象的当前记录
history.replaceState(stateObj, title, [url])
1.3 事件
popstate
history.pushState() 或 history.replaceState() 不会触发popstate事件。 只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法)或 history.go()。
window.addEventListener('popstate', (event) => {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
});
window.onpopstate = function(event) {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
1.4 特点
history 致命的缺点就是当改变页面地址后,强制刷新浏览器时,(如果后端没有做准备的话)会报错,因为刷新是拿当前地址去请求服务器的,如果服务器中没有相应的响应,会出现 404 页面。
2. hash 路由
2.1 属性
//window.location.hash
http://localhost:3000/pagetalk/#abc
//hash: #abc
2.2 事件
onhashchange
window.addEventListener('hashchange',function(){
//监听hash变化,点击浏览器的前进后退会触发
})
2.3 特点
-
后面的是 hash
- hash 改变会直接显示在地址栏,但不会重新加载页面
- 通过监听 window 的 hashchange 事件,来改变页面显示
- 首次加载、hash值改变都会触发 hashchange 事件。