hash
路由
利用hash实现路由切换
<html lang="en">
<head>
<style>
#root{
height: 200px;
border: 1px solid red;
}
</style>
</head>
<body>
<a href="#/a">跳转到/a</a>
<a href="#/b">跳转到/b</a>
<div id="root"></div>
<script>
let container = document.getElementById('root');
window.addEventListener('hashchange',function (e) {
console.log(e);
container.innerHTML = `当前的路径是${window.location.hash.slice(1)}`;
})
</script>
</body>
</html>
- 当通过
hash
切换路由的时候回触发hashchange
事件 - 通过
window.location.hash
可以拿到当前页面的hash
值
Browser
路由
利用
H5——API
实现路由切换
history
对象
提供了操作浏览器会话历史的接口
- 【1】
back
跳到上一个路径,作用同浏览器的回退按钮 - 【2】
forward
跳到下一个路径,作用同浏览器的前进按钮 - 【3】
go
跳到某个路径- 【3-1】参数相对于当前路径的队列数字,例如
go(1) === forword()
,go(-1) === back()
;
- 【3-1】参数相对于当前路径的队列数字,例如
- 【4】
length
表示当前路径队列中存储的路径个数 - 【5】
pushState
在当前路径队列中增加新的路径,并且跳转到新路径;length + 1
- 【5-1】参数三个
history.pushState({name:'新的状态'},'新的标题(已经废弃)','/新的路径')
- 【5-1】参数三个
- 【6】
replaceState
在当前的路径队列中用新的替换当前路径;length
不变- 【6-2】参数同
pushState
- 【6-2】参数同
原理
<html lang="en">
<head>
<style>
#root {
height: 200px;
border: 1px solid red;
}
</style>
</head>
<body>
<button onclick="push('/a')">/a</button>
<button onclick="push('/b')">/b</button>
<button onclick="push('/c')">/c</button>
<div id="root"></div>
<script>
let container = document.getElementById('root');
/**
* 监听弹出状态的事件(出栈操作)
*/
window.onpopstate = function (e) {
console.log(e);
container.innerHTML = e.state.to;
}
function push(to) {
/**
* pushState (入栈操作)
* 三个参数 1.新的状态对象 2.标题(已经废弃) 3.跳转到的路径
*/
window.history.pushState({ to }, null, to);
}
</script>
</body>
</html>
- 由上图可以看出当点击路由按钮的时候实现了路径的切换
- 点击浏览器的回退或者前进的时候实现了路径的切换和视图的切换(即触发了
window.onpopstate
) - 但是我们想要的效果应该是点击路由切换按钮的时候也进行视图的切换,文章前的你肯定跟我有一样的想法——绑定
window.onpushstate
事件,但是很遗憾,浏览器并没有给我们提供这个事件。
优化pushState
&& 实现onpushstate
方法——实现点击路由切换按钮同时进行视图切换
let oldPushState = window.history.pushState; // 保存原有的pushState方法;
window.history.pushState = function(state,title,url){
onpushstate(state,title,url); // 调用我们手写的onpushstate切换视图
oldPushState.call(window.history,state,title,url); // 调用原有的pushState方法实现路由切换
}
window.onpushstate = function(state,title,url){
container.innerHTML = state.to || url;
}
写在最后
文章主要是从底层的角度剖析了单页面应用路由的实现原理,三大框架的路由原理也是基于这个底层思想实现,后续会为大家带来
React-Router
的源码解析;如果觉得写的还可以帮忙点个👍,😉小生将不胜感激🤘。