把不同路由对应不同内容或页面的任务交给前端来做,之前通过服务端根据的不同返回不同的页面实现
前端路由实质上就是检测URL的变动,截获URL地址,通过解析、匹配路由规定实现UI更新
单页面应用中的路由分为hash和history模式

hash模式

监听浏览器地址hash值变化,执行事件
hash会在浏览器URL后增加#号
一个完整的的URL包含:协定、域名、端口、虚拟目录、文件名、参数、锚
比如https://www.google.com/#abc中的hash值为abc特点:hash的变化不会刷新页面,也不会发送给服务器
但hash的变化会被浏览器记录下来,来指导浏览器中的前进和后退
window.location.hash变化触发窗口onhashchange事件,监听hash变化
触发路由时视图容器更新一多数前端框架哈希路由的实现原理
触发hashchange的情况

1
2
3
4
5
window.location.hash='abc';
let {hash}=window.location
window.addEventListener('hashchange',function(){
//监听hash变化
})

特点

兼容性好
路径在#后面,不好看

history模式

H5新特性,允许直接修改前端路由,更新URL但不重新发请求,history可自定义地址
window.history属性指向History对象,表示当前窗口的浏览历史,保存了当前窗口访问过的所有页面网址
由于安全原因,浏览器不允许脚本读取这些地址,但允许在地址间导航

1
2
3
4
//后退到前一个网址
history.back()
//等同于
history.go(-1)

浏览器工具栏的“前进”和“后退”按钮,就是对History对象进行操作
History对象主要有两个属性
History.length:当前窗口访问过的网址数量(包括当前网页)
History.state:History堆栈最上层的状态值(详见下文)

1
2
3
4
5
//当前窗口访问过多少个网页
window.history.length
//History对象的当前状态
//通常是undefined
window.history.state

history.back(history.forward()history.go()
用于在历史之中移动

  • History.back():移动到上一个网址,等于点击浏览器后退键。对于第一个访问的网址,该方法无效
  • History.forward():移动到下一个网址,等于点击浏览器前进键。对于最后一个访问的网址,该方法无效果
  • History.go():接受一个整数作为参数,以当前网址为基准,移动到参数指定的网址,go(1)相当于
    forward(),go(-1)相当于back()。如果参数超过实际存在的网址范围,该方法无效;如果不指定参数,默认
    0,相当于刷新页面

history.pushState()
在历史中添加一条记录,不会导致页面刷新

1
window.history.pushState(state,title,url)
  • state:对象,触发popstate事件将该对象传递到新页面。不需要可以填null
  • tit1e:新页面标题。但现在所有浏览器都忽视这个参数,所以可以填空串
  • url:新网址,必须与当前页面在同域。地址栏将显示这个网址
    假定当前网址是example.com/1.html,使用pushState()在浏览记录(History对象)中添加一个新记录
1
2
var stateobj =foo:'bar'}
history.pushState(stateobj,'page 2','2.html');

添加新记录后,浏览器地址栏显示example.com/2.html,但不会跳转到2.html,也不会检查2.html是否存在,
它只是成为浏览历史的最新记录。这时,在地址栏输入一个新的地址(如访问go0g1.com),然后点击倒退按钮,页
面的URL将显示2.htmL;再点击一次倒退,URL将显示1.html
pushState()不触发页面刷新,只导致History对象变化,地址栏有反应
使用该方法后,可以用History.state读出状态对象

1
2
3
var stateobj =foo:'bar'};
history.pushstate(stateobj,'page 2','2.html');
history.state /{foo:"bar"}

如果oushState的URL参数设置了一个新的锚点值(即hash),不会触发hashchange事件。反过来,如果URL
的锚点值变了,会在History对象创建一条浏览记录
如果pushState()方法设置了一个跨域网址,报错

1
2
3
/报错
//当前网址为http://example.com
history.pushState(null,'','https://twitter.com/hello');

pushStat想要插入一个跨域的网址,导致报错。防止恶意代码让用户以为他们是在另一个网站上,因为这个方法
不会导致页面跳转
history.replaceState()
修改History当前记录,其他与oushState()一模一样
假定当前网页是example.com/example.html

1
2
3
4
5
6
7
8
9
10
11
12
history.pushstate({page:1},'title 1','?page=1')
//URL显示为http://example.com/example.html?page=1
history.pushState({page:2},'title 2','?page=2');
//URL显示为http://example.com/example.html?page=2
history.replaceState({page:3},'title 3','?page=3');
//URL显示为http://example.com/example.html?page=3
history.back()
//URL显示为http://example.com/example.html?page=1
history.back()
//URL显示为http://example.com/example.html
history.go(2)
//URL显示为http://example.com/example.html?page=3

popstate事件
当同一个文档的浏览历史变化触发popstate
注意
“仅调用pushState()/replaceState(),不会触发。
只有点击浏览器倒退/前进,或调用History.back()、History.forward()、History.go()才会触发
·只针对同一个文档,如果浏览历史切换,导致加载不同文档,不会触发
popstate指定回调函数

1
2
3
4
5
6
7
8
9
window.onpopstate function (event){
console.log('location:'document.location);
console.log('state:'JSON.stringify(event.state));
}
//或者
window.addEventListener('popstate',function (event){
console.log(location:'document.location);
console.log('state:'JSON.stringify(event.state));
);

回调函数参数event事件对象,它的state:指向当前状态对象,这个state.也可以通过history对象读取

1
var currentstate=history.state;

页面第一次加载不会触发popstate事件
特点
路径正规
兼容性不比hash,需服务端支持
对于一个应用而言,url的改变(不包括hash值改变)只能由下面三种情况引起:

  • 点击浏览器的前进或后退按钮=>可以监听popstate事件
  • 点击a标签
  • JS触发history.pushState()、history.replaceState()