前端路由实现-hash

window.location 处理哈希的改变时不会重新渲染页面,而是当作新页面加到历史记录中,这样我们跳转页面就可以在 hashchange 事件中注册 ajax 从而改变页面内容。

分析

angular 1.x的路由是直接引入html文件的,所以从这一点逐步分析。

1、我们在angular 1.x的路由中会看到 #,这个 # 有两种意思,一种是锚点,也就是单页面跳转到具体的块div;第二种也就是我们要说的,路由中的#,路由里的 # 不叫锚点,我们称之为 hash,大型框架的路由系统大多都是哈希实现的。

2、根据监听哈希变化触发的事件 —— hashchange 事件

3、加载页面采用jquery.ajax()load() 方法

开工

一:简单介绍load()方法

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="router">

</div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
//下面两种方法都可以引入一个html文件的内容到id=router中
$.ajax({
url:'./test.html',
type:'get',
success:function(res){
$('#router').html($(res));
}
});
// $('#router').load('./test.html');

同级目录下test.html

1
2
3
4
5
6
7
8
9
<section>
<div>ss</div>
<div id="warp">11</div>
<div class="warp">22</div>
</section>

<script>
$('#router').css('color','red');
</script>

ajax引入html

了解更多:ajax加载html文件

二:写入router方法

router.js

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
43
44
function Router(){
this.routes={};
this.currentURL='';
}

//配置 定义方法
Router.prototype.route = function(path,callback){
this.routes[path] = callback || function(){};
}

//刷新 根据load 和 hashchange 来加载方法
Router.prototype.refresh = function(){
this.currentURL = location.hash.slice(1) || '/index';
this.routes[this.currentURL]();
}

//注册load 和 hashchange 事件
Router.prototype.init = function () {
window.addEventListener('load',this.refresh.bind(this),false);
window.addEventListener('hashchange',this.refresh.bind(this),false);
}

//方法 在hashchange 和 load 触发的时候触发这个方法
function display_page(url){
$("#router").load(url)//引入页面
}

window.Router = new Router();
window.Router.init();



//配置 不推荐写在一个文件,重新写一个router配置文件更好维护
Router.route('/index',function(){
display_page('./main.html');
})

Router.route('/news',function(){
display_page('./news.html');
})

Router.route('/about',function(){
display_page('./about.html');
})

index.html

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
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>前端路由实现</title>
<style>
.warp{
width:400px;
height:400px;
border:1px solid grey;
margin:0 auto;
}
.nav{
border-bottom:1px solid grey;
}
.nav li{
display:inline-block;
list-style:none;
}
.nav li a{
display:inline-block;
text-decoration: none;
padding:10px 15px;
}
.router{
padding:20px;
}
</style>

</head>
<body>
<section class="warp">
<div class="nav">
<ul>
<li><a href="#/index">index</a></li>
<li><a href="#/news">news</a></li>
<li><a href="#/about">about</a></li>
</ul>
</div>
<div id="router" class="router">
<!-- 内容加载区域 -->
</div>
</section>

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="./router.js"></script>

</body>
</html>

最终效果

效果

这次只是做了一下hash的,最新的history API还不是很懂,等明白了再做一个history版的,这样就不用看到不怎么友好的#了!

代码: router(hash)
演示: 演示地址