前端路由实现(history)

了解:

HTML5 history新增了两个API:history.pushState和history.replaceState

两个api都接受三个参数

  • 状态对象(state object):一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。

  • 标题(title):FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。

  • 地址(URL): 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。

相同之处是两个API都会操作浏览器的历史记录,而不会引起页面的刷新。不同之处在于pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录

大家可以先在控制台试试,看看地址栏发生了什么变化

window.history.pushState(null, null, "test");window.history.pushState(null, null, "/test");window.history.pushState(null, null, "#/hello");window.history.pushState(null, null, "?name=");
</code></pre>

实例演示

建立html文件,index.html

<!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;}a{cursor: pointer;}</style></head>
<body><section class="warp"><div class="nav">          <ul><li><a href="javascript:void(0)" data-path="index">首页</a></li> <li><a href="javascript:void(0)" data-path="news">新闻</a></li><li><a href="javascript:void(0)" data-path="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>

此时的页面为:


引入js文件router.js

(function(){   history.replaceState(null,null,'');//最开始的状态,采用replace直接替换$('#router').html('<p>显示内容区域</p>')$('a').on('click',function(){console.log(this.text)var text = this.text;$('#router').html('<p>'  text  '</p>')history.pushState(null,null,'#/' text);})
})()

此时点击导航按钮时


  • 此时当点击不同的导航项的时候,地址栏上的路由进行了对应的改变,展现的内容区域也发生了变化。但是实际上这个并没有实现路由的真正含义。因为内容部分的改变是根据事件的触发而获得当前的内容。
  • 此时如果点击浏览的前进和后退按钮,内容是无法监听到地址栏的变化而作出改变的

在此基础上变动一下实现方式,将router.js改为:

// 状态版
(function(){   var count = [0,0,0]$('#router').html('<p>首页</p>' count[0] '<p>新闻</p>' count[1] '<p>关于</p>' count[2])// history.replaceState(count,null,'');//最开始的状态,采用replace直接替换for(var i = 0 ; i<$('a').length; i  ){$('a')[i].index = i$('a').eq(i).on('click',function(){console.log(this.index);var index = this.index;count[index]  ;$('#router').html('<p>首页</p>' count[0] '<p>新闻</p>' count[1] '<p>关于</p>' count[2])console.log(count)history.pushState(count,null,'#/count' count[index]);//之后的状态,需要进行保存})}//监听history其他api导致地址栏url改变事件window.addEventListener('popstate',function(e){console.log(e.state);var state = e.state;$('#router').html('<p>首页</p>' state[0] '<p>新闻</p>' state[1] '<p>关于</p>' state[2])})
})()

此时的思路是做一个状态记录,记录下每个导航按钮被点击的次数。当每次执行点击导航栏切换的时候,通过history.pushState(count, null, '#/count' count[index])这个api,传递了状态对象在内,并在第三个参数中将当前已点击数作为地址栏的显示数据。示例如下:


  • !!当活动历史记录条目更改时,将触发popstate事件。如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对history.replaceState()的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本。
  • 需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back())

此处通过记录下每次的点击次数来解释了pushState的用法以及参数,其实简单的写法可以表达为:

(function(){   var url = '内容展示';history.replaceState(url,null,'');//最开始的状态,采用replace直接替换$('#router').html('<p>' url '</p>')$('a').on('click',function(){console.log(this.text)url = this.text;$('#router').html('<p>'  url  '</p>')history.pushState(url,null,'#/' url);})window.addEventListener('popstate',function(e){console.log(e.state);url = e.state$('#router').html('<p>'  url  '</p>')});
})()

现在的效果看上去其实我们相当于回到了远点,但是解决了无法监听地址栏的地址变化问题,是通过监听popstate来作出响应的。

现在还只是看了这一部分的路由实现机制,要通过监听作出不同的响应。还需要更深入的与hash进行对比。

前端路由实现原理(history)相关推荐

  1. 前端路由工作原理与使用

    单页应用和多页应用 单页面应用:所有功能在一个页面上实现 一个.html 文件 前端路由 组件化开发 网易云音乐 小米移动端 多页应用:与单页应用相对应的,不同的功能通过不同的页面来实现 单页面 - ...

  2. 404 单页应用 报错 路由_详解vue 单页应用(spa)前端路由实现原理

    写在前面:通常 SPA 中前端路由有2种实现方式: window.history location.hash 下面就来介绍下这两种方式具体怎么实现的 一.history 1.history基本介绍 w ...

  3. 前端路由hash和history

    路由: 路由是根据不同的 url 地址展示不同的内容或页面. 后端路由 前端通过不同URL请求后端,后端框架有专门的路由模块用来匹配URL地址,然后根据不同地址和参数调用相关处理程序并返回html页面 ...

  4. 【面试】前端路由hash和history的区别

  5. 前端路由(一) 路由,hash,history

    从vue-router回溯相关原理和知识点 前端路由(二)hash实现路由示例 什么是路由 路由是URL解析对应的函数的映射 从用户的角度看: 记录当前页面状态,例如保存当前页的url再次打开url时 ...

  6. 单页面应用的前端路由原理是什么?

    前置知识 在了解单页面应用的前端路由原理之前,我们先了解下什么事单页面应用,什么是多页面应用,他们之间的区别又是什么? 什么是单页面应用? 单页面应用指的是第一次进入页面的时候会请求一个html文件, ...

  7. 前端路由之hash路由与history路由 Orz

    什么是路由 路由这个概念最先是后端出现的.在以前用模板引擎开发页面时,经常会看到这样 http://hometown.xxx.edu.cn/bbs/forum.php 有时还会有带.asp或.html ...

  8. 单页面应用(SPA)前端路由hash 模式 VS history 模式

    文章目录 单页面应用(SPA) 前端路由的由来 前端路由 hash 模式 history 模式 hash.history优缺点 单页面应用(SPA) 简单的说 SPA 就是一个WEB项目只有一个 HT ...

  9. 监听router_深入揭秘前端路由本质,手写 mini-router

    前言 前端路由一直是一个很经典的话题,不管是日常的使用还是面试中都会经常遇到.本文通过实现一个简单版的 react-router 来一起揭开路由的神秘面纱. 通过本文,你可以学习到: 前端路由本质上是 ...

最新文章

  1. Intel 平台编程总结----缓存的优化
  2. 突发!Windows XP源代码泄露
  3. 网络知识:详解各种路由器组网方法!
  4. IOC操作Bean管理XML方式(有参构造注入属性)
  5. 计算机网络作业5及解答,计算机网络作业八及解答
  6. Just For Fun-用java编个线性回归(一次函数拟合)的图形界面
  7. [译] 学习 Spring Security(四):使用邮箱激活新账户
  8. GlusterFS简单环境部署
  9. QQ聊天记录分析(换新机QQ数据备份还原/Tim迁移)
  10. matlab前馈仿真,基于前馈神经网络的自适应PID控制器仿真研究(MATLAB仿真程序)
  11. Win7下Hyenae的安装
  12. linux 根目录设置777,linux 把根目录设置成777权限的补救方法
  13. java实现qq页面登陆界面
  14. Confluence 表格快捷键
  15. 微信打开网址提示在浏览器中打开的办法
  16. 阿里云轻量服务器WordPress镜像建网站教程(图)
  17. Golang 加密方法
  18. Unreal Engine使用C++入门示例
  19. 元宇宙照进现实 金蝶联手科大讯飞发布“数字员工”
  20. 计算机信息安全法规和道德规范,信息安全法律法规与道德规范ppt

热门文章

  1. c语言队列原理的实现,c印记(十二):队列queue原理与实现
  2. mysql表主键类型_mysql表结构主键类型
  3. 基于锁相环的定时误差调整
  4. nuxt sass 全局变量的问题_Sass入门教程
  5. NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」...
  6. EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换
  7. go Windows Service
  8. FreeRTOS--API函数
  9. 树——平衡二叉树插入和查找的JAVA实现
  10. 今天才知道css hack是什么