什么是路由?

个人理解路由就是浏览器 URL 和页面内容的一种映射关系。

比如你看到我这篇博客,博客的链接是一个 URL,而 URL 对应的就是我这篇博客的网页内容,这二者之间的映射关系就是路由。

其中路由又分为前端路由和后端路由,由于目前是大部门开发模式都是前后端分离开发模式,其大部分应用都是 SPA(simple Page Application,单页面应用),个人的工作也是由后端提供API,我前端来进行整个页面的渲染和路由控制。

前端路由目前实现的原理主要是:URL 的 hashHTML5 的 History

hash 模式

浏览器提供了一些 api 可以让我们获取到URL中带“#”的标识。比如 URL.hash、location.hash。

同时我们可以通过 hashchange 事件来监听hash值的改变,这样就能通过事件监听 url 中 hash 的改变从而改变特定页面元素的显示内容,从而实现前端路由。简单实现代码如下:

<div id="app">
<a href="#/home">home</a>
<a href="#/about">about</a> <div class="router-view"></div>
</div>
// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view'); // 2.监听 hashchange 事件
window.addEventListener('hashchange', () => {
// 3.判断 hash 的改变值,修改路由显示元素的 innerHTMl
switch (location.hash) {
case '#/home':
routerViewEl.innerHTML = 'Home';
break;
case '#/about':
routerViewEl.innerHTML = 'about';
break;
default:
routerViewEl.innerHTML = 'default';
}
});

History 模式

history 接口是 HTML5 新增的, 它有六种模式改变 URL 而不刷新页面。

  • pushState:使用新的路径;
  • replaceState:替换原来的路径;
  • popState:路径的回退;
  • go:向前或向后改变路径;
  • forward:向前改变路径;
  • back:向后改变路径;

其中比较重要的两个 api 是 pushState 和 replaceState 是比较重要的,是实现 history 模式的重要 api。

首先我们用 pushState 来简单实现下,代码如下:

<div id="app">
<a href="/home">home</a>
<a href="/about">about</a> <div class="router-view"></div>
</div>
// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view'); // 2.获取所有路由跳转元素
const aEls = document.getElementsByTagName('a');
// 3.遍历所有 a 元素,注册事件监听点击
for (let aEl of aEls) {
aEl.addEventListener('click', (e) => {
// 4.阻止默认跳转
e.preventDefault();
// 5.获取 href 属性
const href = aEl.getAttribute('href');
// 6.执行 history.pushState
history.pushState({}, '', href);
// 7.判断 pathname 路径的改变
switch (location.pathname) {
case '/home':
routerViewEl.innerHTML = 'Home';
break;
case '/about':
routerViewEl.innerHTML = 'about';
break;
default:
routerViewEl.innerHTML = 'default';
}
});
}

相同之处是两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。

不同之处在于,pushState 会增加一条新的历史记录,而 replaceState 则会替换当前的历史记录。其内部原理是 pushState 每次前进一次页面都是入栈操作,每次返回又是出栈,因此使用 pushState ,浏览器可以执行本身的前进后退操作,其内部就是一个入栈出栈;而 replaceState 就不可,它是把每次栈底的数据替换,而不是入栈。

pushState 栈:[]->点击 home 入栈->[home]->点击 about 入栈->[home,about]->浏览器回退,about 出栈->[home]

replaceState 栈:[]->点击 home 入栈->[home]->点击 about 替换栈底->[about]

如果把代码改成 replaceState 实现。那么就不能操作浏览器上面的前进后退操作。

// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view'); // 2.获取所有路由跳转元素
const aEls = document.getElementsByTagName('a');
// 3.遍历所有 a 元素,注册事件监听点击
for (let aEl of aEls) {
aEl.addEventListener('click', (e) => {
// 4.阻止默认跳转
e.preventDefault();
// 5.获取 href 属性
const href = aEl.getAttribute('href');
// 6.执行 history.replaceState
// history.pushState({}, '', href);
history.replaceState({}, '', href);
// 7.判断 pathname 路径的改变
switch (location.pathname) {
case '/home':
routerViewEl.innerHTML = 'Home';
break;
case '/about':
routerViewEl.innerHTML = 'about';
break;
default:
routerViewEl.innerHTML = 'default';
}
});
}

参考文章

前端路由的两种实现原理

前端路由原理之 hash 模式和 history 模式的更多相关文章

  1. 【前端路由】Vue-router 中hash模式和history模式的区别

    咱们今天说说VUE路由的hash模式与history模式的区别,这个也是面试常问的问题,不要小看这道题其实问到这里的时候那个面试官应该是个大牛,开发经验丰富,这个题其实就是考验你的开发经验是否属实. ...

  2. 前端路由的两种模式: hash 模式和 history 模式

    随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...

  3. 前端路由的两种模式:hash(#)模式和history模式(转)

    随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...

  4. Vue路由的hash模式与history模式的区别?

    1.首先router有两种模式:hash模式(默认).history模式(需配置mode: 'history') hash和history的区别?   hash                    ...

  5. 前端路由原理及vue-router介绍

    前端路由原理本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新.目前单页面使用的路由就只有两种实现方式 hash history www.test.com/##/ 就是 Ha ...

  6. vue-router的hash模式与history模式的对比

    Vue-router 中hash模式和history模式的关系在vue的路由配置中有mode选项 最直观的区别就是在url中 hash 带了一个很丑的 # 而history是没有#的mode:&quo ...

  7. Vue-router 中hash模式和history模式的区别

    实际上存在三种模式: Hash: 使用URL的hash值来作为路由.支持所有浏览器. History: 以来HTML5 History API 和服务器配置.参考官网中HTML5 History模式 ...

  8. hash模式与history模式

    随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...

  9. Vue中hash模式和history模式的区别

    vue-router 中hash模式和history模式. 在vue的路由配置中有mode选项,最直观的区别就是在hash模式下的地址栏里的URL夹杂着‘#’号 ,而history模式下没有.vue默 ...

随机推荐

  1. SpringBoot 默认json解析器详解和字段序列化自定义

    前言 在我们开发项目API接口的时候,一些没有数据的字段会默认返回NULL,数字类型也会是NULL,这个时候前端希望字符串能够统一返回空字符,数字默认返回0,那我们就需要自定义json序列化处理 Sp ...

  2. JavaEE在线就业班2.0-(1)-《博学谷》

    JavaEE在线就业班2.0学习笔记 1. Java概述 1.1 Java语言背景介绍(了解) 语言:人与人交流沟通的表达方式计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言Java语言是美国 ...

  3. 仅用CSS实现图片渲染特效 (有学习到了)

    前言 实现图片高亮效果等特效,就不得不提到CSS3的滤镜filter属性,CSS过滤器是一个强大的工具,可以使用它来实现不同的视觉效果(有点像浏览器的Photoshop过滤器).CSS filter属 ...

  4. Arp欺骗和DNS投毒

    中间人攻击 ARP缓存攻击 ARP(Address Resolution Protocol,地址解析协议)是一个位于TCP/IP协议栈中的网络层,负责将某个IP地址解析成对应的MAC地址.简单来说,就 ...

  5. Eclipse的XML编辑器解决方案

    现在使用的Eclipse SDK 3.7.2里没有XML编辑器,无法进行语法高亮,也没有格式化(按层次控制缩进量)和设计视图,很不方便.对于ant文件,可以用Ant Editor来打开,ivy文件在装 ...

  6. 移动端 CPU 的深度学习模型推理性能优化——NCHW44 和 Record 原理方法详解

    用户实践系列,将收录 MegEngine 用户在框架实践过程中的心得体会文章,希望能够帮助有同样使用场景的小伙伴,更好地了解和使用 MegEngine ~ 作者:王雷 | 旷视科技 研发工程师 背景 ...

  7. 我写一篇文章就是要批评CSDN! 因为蓝湖3.0的更新

    对于开发者,经常会使用,学习到各种环境语言和工具 我们不只是在不断的在搬运知识,更多时候我们也是在 分享我们学到的"新知识", 当我们有幸觉得自己发现了新的知识与技术时,作为分享者 ...

  8. 渲染优化之CSS Containment

    引言 在开始介绍今天的主角 CSS Containment 之前,我们需要了解一些前置知识回流和重绘,方便我们理解以及应用的场景. 简单回忆下回流和重绘 回流(Reflow):当浏览器必须重新处理和绘 ...

  9. CVE-2020-2555漏洞复现&&流量分析

    CVE-2020-2555漏洞复现&&流量分析 一.准备环境 windows7: weblogic 12.2.1.4.0 JDK版本为jdk-8u261 关于weblogic搭建可以看 ...

  10. Pikachu-XSS模块与3个案例演示

    一.概述 XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户. 形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致"精心构造"的字符输出在前端时被浏览 ...