原生js实现路由

​ 背景: 再过去,路由切换只出现在后台,前端想要切换到某个页面,就需要向后端请求,随后完成路由切换。但随着spa单页面应用模型的发展,前端路由也逐渐火热,单页面顾名思义就是一个html页面,但当我们点击导航的时候url会改变,网页也会显示不同的内容。简而言之就是js监测url变化,从而改变内容

​ 实现思路:实现前端路由是为了在单页面应用中实现页面切换而不刷新整个页面。原生JavaScript可以通过监听URL的变化来实现简单的路由功能

​ 步骤:

  1. 使用hash实现路由:在URL中使用#后面的部分来表示路由路径,当hash发生变化时,可以通过监听hashchange事件来捕获路由变化。
  2. 动态更新页面内容:根据不同的路由路径,动态更新页面内容,实现页面切换的效果
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//自执行函数
(function (){
// 定义 Router 构造函数
var Router = function (){
this.routers = {} //保存路由
this.curUrl = '' //获取当前的hash
}
// 给构造函数Router原型添加初始化方法
Router.prototype.init = function() {
window.addEventListener('hashchange', this.reloadPage.bind(this))
}

Router.prototype.reloadPage = function(){
//获取当前hash值
this.curUrl = location.hash.substring(1) || '/'
//运行hash值对应的函数
this.routers[this.curUrl]()
}

Router.prototype.map = function(key,callback){
this.router[key] = callback
}
//暴露出去,挂载到oRou
window.oRou = Router
}){}
//实例化
var oRouter = new oRou()
oROuter.init()

//获取路由并展示main可视区内容
oRouter.map('/', ()=>{
var oSidebar = document.querySelector('sidebar')
oSidebar.innerHTML = '我是主页'
})
oRouter.map('/', ()=>{
var oSidebar = document.querySelector('sidebar')
oSidebar.innerHTML = '我是html页面'
})
oRouter.map('/', ()=>{
var oSidebar = document.querySelector('sidebar')
oSidebar.innerHTML = '我是css页面'
})

其他:

  1. 参数传递:可以在路由路径中传递参数,通过解析参数来动态展示页面内容。
  2. 路由拦截:可以在路由处理函数中增加拦截逻辑,实现路由权限控制或其他逻辑。
  3. 路由动画:可以在页面切换时添加动画效果,提升用户体验
  • 使用history

​ 通过history对象的popstate事件,我们可以在浏览历史记录发生变化时捕获路由的变化

​ 我们通过window.addEventListener('popstate', function(event) { ... })来监听popstate事件,当浏览历史记录发生变化时,会触发该事件。在事件处理函数中,我们可以获取当前的URL,从而实现路由变化的监听和处理。

通过监听history对象的路由变化,我们可以实现更灵活的路由管理,同时可以结合pushStatereplaceState等方法来改变路由并触发相应的事件。

1
2
3
4
5
6
7
8
9
10
11
12
// 监听popstate事件
window.addEventListener('popstate', function(event) {
// 处理路由变化
console.log('Current URL: ' + document.location.href);
});

// 改变路由并触发popstate事件
history.pushState({page: 1}, "title 1", "/page1");
history.pushState({page: 2}, "title 2", "/page2");
history.replaceState({page: 3}, "title 3", "/page3");
history.back(); // 模拟后退操作
history.forward(); // 模拟前进操作