把不同路由对应不同内容或页面的任务交给前端来做,之前通过服务端根据的不同返回不同的页面实现
前端路由实质上就是检测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的情况
- URL变化(包括浏览器的前进、后退)修改window.location.hash
- 浏览器发送http://www.baidu.com/至服务器,请求完毕后设置散列值为#/home
- 只修改hash部分,不发请求
- a标签可设置页面hash,浏览器自动设置hash
1 | window.location.hash='abc'; |
特点
兼容性好
路径在#后面,不好看
history模式
H5新特性,允许直接修改前端路由,更新URL但不重新发请求,history可自定义地址
window.history属性指向History对象,表示当前窗口的浏览历史,保存了当前窗口访问过的所有页面网址
由于安全原因,浏览器不允许脚本读取这些地址,但允许在地址间导航
1 | //后退到前一个网址 |
浏览器工具栏的“前进”和“后退”按钮,就是对History对象进行操作
History对象主要有两个属性
History.length:当前窗口访问过的网址数量(包括当前网页)
History.state:History堆栈最上层的状态值(详见下文)
1 | //当前窗口访问过多少个网页 |
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 | var stateobj =foo:'bar'} |
添加新记录后,浏览器地址栏显示example.com/2.html,但不会跳转到2.html,也不会检查2.html是否存在,
它只是成为浏览历史的最新记录。这时,在地址栏输入一个新的地址(如访问go0g1.com),然后点击倒退按钮,页
面的URL将显示2.htmL;再点击一次倒退,URL将显示1.html
pushState()不触发页面刷新,只导致History对象变化,地址栏有反应
使用该方法后,可以用History.state读出状态对象
1 | var stateobj =foo:'bar'}; |
如果oushState的URL参数设置了一个新的锚点值(即hash),不会触发hashchange事件。反过来,如果URL
的锚点值变了,会在History对象创建一条浏览记录
如果pushState()方法设置了一个跨域网址,报错
1 | /报错 |
pushStat想要插入一个跨域的网址,导致报错。防止恶意代码让用户以为他们是在另一个网站上,因为这个方法
不会导致页面跳转
history.replaceState()
修改History当前记录,其他与oushState()一模一样
假定当前网页是example.com/example.html
1 | history.pushstate({page:1},'title 1','?page=1') |
popstate事件
当同一个文档的浏览历史变化触发popstate
注意
“仅调用pushState()/replaceState(),不会触发。
只有点击浏览器倒退/前进,或调用History.back()、History.forward()、History.go()才会触发
·只针对同一个文档,如果浏览历史切换,导致加载不同文档,不会触发
popstate指定回调函数
1 | window.onpopstate function (event){ |
回调函数参数event事件对象,它的state:指向当前状态对象,这个state.也可以通过history对象读取
1 | var currentstate=history.state; |
页面第一次加载不会触发popstate事件
特点
路径正规
兼容性不比hash,需服务端支持
对于一个应用而言,url的改变(不包括hash值改变)只能由下面三种情况引起:
- 点击浏览器的前进或后退按钮=>可以监听popstate事件
- 点击a标签
- JS触发history.pushState()、history.replaceState()