赞
踩
前端路由的本质,是监听 url 地址或 hash 值的改变,来切换渲染对应的页面组件
两种模式的对比
对比 | hash 模式 | history 模式 |
---|---|---|
url 显示 | url 中带"#" | url 中不带"#" |
回车刷新(浏览器刷新按钮) | 页面正常显示 | 后端未配置则页面显示404 |
支持版本 | 支持低版本浏览器和 IE 浏览器 | HTML5 新推出的 API |
hash 模式是一种把前端路由的路径用 # 拼接在真实 url 后面的模式
在hash模式下,本质上是修改window.location.href实现的。
前端路由的改变依托于#锚点,而锚点后边的值我们可以通过修改window.location.hash的值来修改,每一次hash值的变化都会导致触发hashchange这个事件,hash模式就是通过 hashchange 事件来 监听 hash 值的改变从而渲染页面对应的组件。
在hash模式下修改页面不会刷新,因此hash模式不会向后端发送http请求,不会导致浏览器向后端发送请求。
使用 location.hash 获取 hash 值
location 是 window.location 或者 document.location 的简写模式,window.location 对象包含了当前 URL 的信息,并提供了一系列属性来访问和操作 URL。
通过访问 window.location 对象的这些属性,可以方便地获取当前页面的 URL 信息,并且在需要时进行相应的修改。这些属性对于处理 URL 相关的逻辑非常有用。
作用: 实现对当前页面 URL 的重新加载、跳转等操作,方便地进行页面控制和导航
方法
当 URL 的片段标识符(hash 值)更改时,将触发 hashchange 事件 (跟在#符号后面的 URL 部分,包括#符号)。
可以使用 addEventListener 监听 hashchange 事件:
- window.addEventListener('hashchange', function() {
- console.log('hash值被修改了');
- console.log('hashchage 事件被触发了');
- }, false);
使用 onhashchange 事件处理程序
- function locationHashChanged() {
- if (location.hash === '#/about') {
- console.log("欢迎进入about页面");
- }
- }
- window.onhashchange = locationHashChanged;
- // hash值的改变也会触发 window.onpopstate事件,onpopstate事件在 history模式中再做介绍
- window.addEventListener("popstate", () => {
- console.log("popstate 事件被触发了");
- })
直接修改浏览器url地址,添加 hash 值 #/about。可以看出,修改 hash 值会优先触发 popstate 事件,然后再触发 hashchange 事件:
history 是 HTML5 提供的新特性,允许开发者直接更改前端路由,也就是更改 url 地址而无需向后端发送 http 请求。
history 是 window.history 的简写模式,是 History 构造函数的实例化对象。
History 接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录。
也就是说 History 里面保存着当前标签页的所有浏览页面的访问记录。
实例化对象属性
- length 会话历史记录中元素的数目,包括当前加载的页面
- Integer(整型数值)
- scrollRestoration 设置浏览器的默认滚动行为 auto(默认值,浏览器自动滚动) / manual(关闭浏览器自动滚动)
- state 返回一个表示历史堆栈顶部的状态的任意值
- any(任意值)
- back() 在会话历史记录中向后移动一页。如果没有上一页,则此方法调用不执行任何操作 window.history.back()
- forward() 在会话历史中向前移动一页 window.history.forward();
- go() go方法从会话历史记录中加载特定页面 window.history.go(-1); 负值表示向后移动back(),正值表示向前移动forward(); 值为0或不传时重新加载当前页面
- pushState() 向当前浏览器历史中添加记录 history.pushState(state, title[, url])
- replaceState() 修改当前历史记录实体,可以更新 state 对象以及 URL 地址。 history.replaceState(stateObj, title[, url]);
history.pushState() 方法接收三个参数:
- state:一个对象,popState 事件触发时,state 对象会传入回调函数。如无需传参,则设置为 null 。
- title:新页面的标题,但是所有浏览器目前都忽略这个值,因此可以设置为空字符串 "" 或者 null 。
- url:新的网址地址,必须与当前页面处于同一个域下,浏览器的地址栏将显示这个网址。
接下来做一个测试,有一个 a.html 页面:
使用 pushState 方法添加一条记录到 History 会话历史中,并传参, pushState 方法只是更新了 url 地址,而页面未跳转。
history.replaceState()的使用
history.replaceState() 方法接收的参数与 history.pushState() 方法相同,唯一的不同是,使用 replaceState 会更新当前页面的记录,包括 state 对象和 URL 地址。
举个例子,使用 pushState 添加 a.html b.html c.html 三个记录,然后使用 replaceState 添加 d.html ,最后查看历史记录栈中收录了几条历史记录:
由上图可知,历史记录栈中只存有三条记录,即 ["a.html", "b.html", "d.html"]。原因就是 replaceState 将 c.html 替换为了 d.html。
所以使用 history.back() 会返回 b.html。
使用 history.forward() 也只会显示 d.html :
window.onpopstate 事件是用来监听浏览历史记录变化的。
调用 history.pushState() 或者 history.replaceState() 不会触发 popstate 事件。popstate 事件只会在浏览器某些行为下触发,比如点击前进、后退按钮(或者在 JavaScript 中调用 history.back()、history.forward()、 history.go() 方法)。即,在同一文档的两个历史记录条目之间导航会触发该事件。
使用 addEventListener 监听 popstate 事件:
- window.addEventListener('popstate', function(event) {
- console.log(event);
- }, false);
使用 onpopstate 事件处理程序
- function historyStateChanged(event) {
- console.log(event);
- }
- window.onpopstate= historyStateChanged;
- // 测试,使用 popstate 监听记录栈的改变:
- window.addEventListener("popstate", (event) => {
- console.log(event);
- })
使用 pushState 以及 replaceState 并未触发 popstate 事件:
- 使用 history.back() ,触发了 popstate 事件并打印了参数 event
- event事件对象中保存着 state 对象。
在 history 下,你可以自由的修改 path,但刷新页面时,如果服务器中没有相应的响应或者资源,则会出现404页面,因为刷新页面会发送 http 请求。也就是说,使用 history 路由模式,需要通过服务端来允许地址可访问,后端也必须配置了当前资源路径地址才行。
如果后台部署使用了 nginx,可以对 nginx 进行如下配置来解决页面刷新问题(摘录):
- server {
- listen 8080;
- server_name localhost;
- location / {
- alias /Data/nginx/portal/;
- index /index.html;
- try_files $uri $uri/ /index.html;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。