路由原理
Chao 工程师

路由原理

hash路由(核心api:hashchange事件)

利用a标签,并阻止默认事件。通过hashchange事件监听hash值的变化,替换掉目标区域的html内容

1
2
3
4
5
6
7
8
9
<h1>hash 路由</h1>
<a href="#user">用户</a>
<a href="#about">关于</a>

<div id="content"></div>

<!-- 下面一开始就被隐藏了 -->
<div id="user">这里是用户模块</div>
<div id="about">这里是关于模块</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const $user = document.querySelector('#user')
const $about = document.querySelector('#about')
const $content = document.querySelector('#content')

hashRender()
window.addEventListener('hashchange', function(e) {
hashRender()
})

function hashRender () {
if (location.hash === '#user') {
$content.innerHTML = $user.innerHTML
} else {
$content.innerHTML = $about.innerHTML
}
}

history路由(核心api:pushState/replaceState、popstate)

使用点击事件,将对应的名称通过pushState / replaceState方法添加到浏览器history对象中,并在此时根据模块名称替换掉目标区域的html内容。随后,当浏览器发生后退、前进的行为时,可以通过popstate事件监听到location.pathname,最后再做更新。

![image-20230312155110164](data:image/svg+xml,)

1
2
3
4
5
6
7
8
9
<h1>history 路由</h1>
<span class="route user">用户</span>
<span class="route about">关于</span>

<div id="content"></div>

<!-- 下面一开始就被隐藏了 -->
<div id="user">这里是用户模块</div>
<div id="about">这里是关于模块</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const $user = document.querySelector('#user')
const $about = document.querySelector('#about')
const $content = document.querySelector('#content')
const $route = document.querySelectorAll('.route')
let url = location.pathname;

function historyRender (name) {
if (name === 'user') {
$content.innerHTML = $user.innerHTML
} else {
$content.innerHTML = $about.innerHTML
}
}

for (let i = 0; i < $route.length; i++) {
const route = $route[i];
route.addEventListener('click', function(e) {
const name = e.target.classList[1]
historyRender(name)
window.history.pushState(null, null, name)
})
}

window.addEventListener('popstate', function(e) {
historyRender(location.pathname.slice(1))
})

onpopstate 事件只能监听到由浏览器触发的历史记录变化,例如点击浏览器的==前进==或==后退==按钮,或者调用 history.back()history.forward() 方法。

如果你在 JavaScript 中调用 history.pushState()history.replaceState() 方法来修改浏览器的历史记录,那么不会触发 onpopstate 事件。

因此,如果你想要在调用 pushState()replaceState() 方法后立即获取路由变化,可以在调用这两个方法后手动触发 popstate 事件,例如

1
2
history.pushState({}, '', '/new-path');
window.dispatchEvent(new PopStateEvent('popstate'));

在上面的代码中,我们先调用 pushState() 方法来修改浏览器的历史记录,并修改当前页面的 URL 为 /new-path。然后,手动触发 popstate 事件,这会立即触发绑定在 window.onpopstate 上的事件处理函数,并获取到新的路由信息

 Comments