前端路由主要是由1.window.history,2.监听window对象的hashchange事件 hash路由 两种方式,本文主要讲解history路由。
为什么需要history对象?
单页面应用通过url来确定页面,点击不同的url来渲染相应页面,以前只能通过监听url中的hash来确定页面,这导致当时的单页应用无法使用浏览器的前进/后退来切换页面,为了解决这个问题,history对象应运而生。当页面的url或者hash发生变化的时候,浏览器会自动将新的url push到history对象中。history对象内部会维护一个state数组,记录url的变化。在浏览器进行前进/后退操作的时候,实际上就是调用history对象的对应方法(forward/back),取出对应的state,从而进行页面的切换。
history对象
每个标签都有一个独立的历史记录,里面维护着一条或多条记录。每条记录保存了对应 URL 的一些状态,仅能在当前页面的 window.history 对象读取到。
1. history.length
- 只读属性,有几条url,就有几个长度,前进或后退页面不会改变length
2. history.back() .forward() .go()
- 仅调用以上三个方法,不会使得历史记录或 history.length 发生改变。
- 调用以上三个方法,通常是从浏览器缓存中加载页面。在 Network 选项卡中往往可以看到类似 from disk cache 的字样。
- 当超出了当前标签的历史记录范围,调用以上三个方法都不会执行任何操作,默默地失败且不报错。
- 请注意,若后退/前进时,只是锚点发生变化,是不会重新加载页面。
3. history.state
- 只有通过 pushState() 和 replaceState() 方法产生的历史记录,这个属性才会有相应的值,否则为 null
- eg:
{
back: '/reactVite',
current: '/home',
forward: '/reactVite',
position: 53,
replaced: true,
},
该参数可以记录一些前进去哪,后退去哪的信息,当点击go或者前进按钮时,就能取出来调用。
4. history.pushState
参数1,是为参数3所使用的,当跳转参数3的页面时,指定操作触发了popstate事件时,就会拿到这个参数一来用。
history.pushState({}, ‘title’, ‘url’)
- 在当前url文档,产生一条新的记录,并保存在历史记录栈顶里面,同时修改当前指针,跳转页面,而且 history.length 也会增加
- 请注意,它并
不会重载页面
若要重载,可接上location.reload()
window.history.pushState({name: 'xxx'}, '', '/history/page2')
location.reload()
5. history.replaceState
history.replaceState({}, ‘title’, ‘url’)
- replaceState() 也总会产生一条新记录,并用新记录
替换掉当前页面
对应的历史记录,replaceState不会改动浏览器历史堆栈的当前指针 - 请注意,它并
不会重载页面
若要重载,可接上location.reload()
6. popstate 事件
每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。
如果当前活动的历史记录项是被 pushState 创建的,或者是由 replaceState 改变的,那么 popstate 事件的状态属性 state 会包含一个当前历史记录状态对象的拷贝。
- 注意,pushState 或 replaceState 事件调用并不会触发 目标页面的onpopstate调用,只有到达新页面时,通过点击浏览器后退/前进按钮,或者通过脚本调用 history.back()、history.forward()、history.go() (go(0) 除外)方法,popstate 事件才会被触发,才能拿到pushState 或 replaceState 推送的state,作相应操作。
location.href 与 history.pushState有什么区别?
- 1.使用location.href跳转后页面会发起新的文档请求,而history.pushState不会。
2.location.href可以跳转到其他域名,而history不能。
3.location.href与history都会往历史列表中添加一条记录。