一. hash
锚点使用方式
- 超链接方式
- location.hash 方式
- location.href 方式
1. <a href="#anchor1"> 跳转到锚点1</a>
2. location.hash='anchor1'
3. location.href='anchor1'
注意:
① 当hash值发生变化时,会出发 onhashchange 事件.
② location.hash 前后赋相同值时 不会多次触发 而location.href 可以多次触发
<div name="anchor1" >锚点1</div>
<div name="anchor2" >锚点2</div>
// or
<div id="anchor1" >锚点1</div>
<div id="anchor2" >锚点2</div>
当hash发生变化时,地址栏地址会发生变化,但是并不会向服务器重新发现请求,页面不会刷新
二. history
History 对象属性
| 属性名 | 描述 |
|---|---|
| length | 浏览器历史列表中的 URL 数量 |
| scrollRestoration | 允许 web 应用程序在历史导航上显式地设置默认滚动恢复行为。此属性可以是自动的(auto)或者手动的(manual) |
| state(只读) | 浏 览器在当前URL下的一个状态信息。默认是null |
History 对象方法
| 方法名 | 描述 |
|---|---|
| back() | 加载 history 列表中的前一个 |
| forward() | 加载 history 列表中的下一个 URL |
| go(number丨URL) | 跳转到指定页面,参数url字符串(不是标准规则) |
| pushState(state, title, url) | 向当前浏览器会话的历史堆栈中添加一个状态 |
| replaceState(state, title, url) | 修改当前历史记录实体 |
浏览器的前进后退,back(), forward(), go() 会出发window.onpopstate 事件
路由的实现
url路由三种变化的方式
- 在页面通过事件修改地址
- 浏览器的前进后退,back(), forward(), go() 导致地址栏发生变化
- 在地址栏直接输入访问
所以无论是 hash模式 还是history模式.我们只要对着3种操作进行监控就可以实现前端路由功能
① 通过事件修改地址
<body>
<button id="button">修改url</button>
<div id="view" />
</body>
<script>
const button = document.getElementById("button")
const view = document.getElementById("view")
// hash 模式
button.onclick = () => {
location.hash='componentOne'
if(location.hash==="#componentOne"){
content.innerHTML="组件1"
}}
//or
//history 模式
button.onclick = () => {
history.pushState({ componentId: 1 }, "", "/componentOne")
if(location.pathname==="/componentOne"){
content.innerHTML="组件1"
}}
</script>
点击按钮时通过判断hash或pathname 去渲染对应的组件 ,并且通过 location.hash和 history.pushState 去修改url地址 ,从而达到不刷新浏览器而修改地址
②通过 前进后退修改地址
<script>
// hash 模式
window.addEventListener('hashchange',()=>{
if(location.hash==="#componentOne"){
content.innerHTML="组件1"
}}
)
//or
//history 模式
window.addEventListener('popstate',()=>{
if(location.pathname==="/componentOne"){
content.innerHTML="组件1"
}}
}
</script>
前进后退,back(), forward(), go() 会触发 onhashchange和onpopstate
③ 在地址栏直接输入访问
<script>
// hash 模式
window.addEventListener("DOMContentLoaded", () => {
if(location.hash==="#componentOne"){
content.innerHTML="组件1"
}}
})
//history 模式
window.addEventListener("DOMContentLoaded", () => {
if(location.pathname==="/componentOne"){
content.innerHTML="组件1"
}}
})
</script>
dom 渲染完成后触发事件, 注意history模式时候 需要后端配合 将路径 '/a/xxxxx' 重新定向到 '/a' 地址上