前端路由实现原理(history)

前端路由实现(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进行对比。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity 删除服务器项目,在吗?有个支持批量构建项目的好东西推荐给你

Unity Build Server是一种全新的项目构建辅助工具&#xff0c;它可以指定硬件设备&#xff0c;专门用于构建项目版本&#xff0c;帮助工作室大规模构建项目&#xff0c;提高团队生产力。很多人在选择Unity时并不会首先考虑到项目构建问题&#xff0c;而随着项目变得更大、更复杂…

使用WSO2 ESB构建制造服务总线(MSB)

在开始讨论本主题之前&#xff0c;我想介绍一些制造业中常用的术语。 术语制造执行系统&#xff08;MES&#xff09;由AMR Research于1990年提出&#xff0c;从先进的制造计算机信息系统的发展&#xff0c;MES概念已经发展了近三十年。 以下是制造执行系统协会&#xff08;MES…

mysql jion 实现原理_MySQL-join的实现原理、优化及NLJ算法

案例分析&#xff1a;selectc.*fromhotel_info_original cleft joinhotel_info_collection honc.hotel_typeh.hotel_typeandc.hotel_idh.hotel_idwhereh.hotel_idis null这个sql是用来查询出 c 表中有 h 表中无的记录&#xff0c;所以想到了用 left join 的特性(返回左边全部记…

python笔记30-docstring注释添加变量

前言 python里面添加字符串注释非常简单&#xff0c;如何将变量放入 python 的函数注释里面呢&#xff1f; docstring也就是给代码加注释的内容了&#xff0c;python可以给函数&#xff0c;类、方法&#xff0c;模块添加注释内容&#xff0c;注释标准格式一般是三个双引号&…

无线路由器在手机上如何连接服务器,192.168.10.1路由器手机怎么设置? | 192路由网...

问&#xff1a;192.168.10.1路由器手机怎么设置&#xff1f;答&#xff1a;192.168.10.1是一个C类的私有IP地址&#xff0c;目前国产的路由器中&#xff0c;睿因路由器使用192.168.10.1作为默认登录地址。鉴于此&#xff0c;下面鸿哥使用睿因路由器来进行演示介绍。温馨提示&am…

Java Mission Control 5.2终于来了! 欢迎7u40!

自从我们上次听说这个叫做任务控制的小东西已经有一段时间了。 它从JRockit一直到现在都被重命名为Java Mission Control。 这是从HotSpot和JRockit融合战略中幸存下来的部分之一。 使用今天的Java SE 7 Update 40&#xff0c;您实际上可以再次使用它。 Java Mission Control …

webview布局适配实践

一、相关概念 1、viewport&#xff1a;移动设备&#xff08;包括webview&#xff09;用来显示网页的那一块区域&#xff1b; 2、devicePixelRatio属性(别名像素比&#xff0c;简称dpr)&#xff1a;window.devicePixelRatio 物理像素 / 独立像素(css中的px)&#xff1b; 3、rem…

尝试连接到服务器时出错请检查虚拟机管理器,Hyper-V尝试连接到服务器出错无效类的解决方法...

Hyper-V尝试连接到服务器出错无效类的解决方法Windows10安装Hyper-V后没有自动连接到本地计算机&#xff0c;手工连接失败&#xff0c;提示&#xff1a;引用内容尝试连接到服务器"DESKTOP-6P9L2HB"时出错。请检查虚拟机管理服务是否正在运行以及是否授权你连接到此服…

你敢在post和get上刁难我,就别怪我装逼了

> 掘金编辑提醒&#xff1a;本文疑似有误&#xff0c;参考 听说「99% 的人都理解错了 HTTP 中 GET 与 POST 的区别」 之前好几次面试都被问到post和get有什么区别&#xff0c;肯定很多同学和我一样说了一大堆什么post比get安全&#xff0c;get比post传的少乱起八糟这样的答案…

昂首阔步:让开发人员喜欢使用您的REST API

随着JAX-RS API的发展&#xff0c;以及今年早些时候在JSR-339下发布的2.0版本&#xff0c;使用出色的Java平台创建REST服务变得更加容易。 但是&#xff0c;极大的简化带来了巨大的责任&#xff1a;记录所有这些API&#xff0c;以便其他开发人员可以快速了解如何使用它们。 不…

thinkphp mysql 更新_THINKPHP5修改数据库数据出现“缺少更新条件”的错误

查询数据库的数据分配显示在页面山修改后的数据准备传递到第三章图里接收数据&#xff0c;然后修改到数据问题出现的环境背景及自己尝试过哪些方法相关代码// 请把代码文本粘贴到下方(请勿用图片代替代码)第一张图代码public function edit(){$db_01new DB();$id_editRequest::…

[No0000187]可能是把Java内存区域讲的最清楚的一篇文章

写在前面&#xff08;常见面试题&#xff09; 基本问题&#xff1a; 介绍下 Java 内存区域&#xff08;运行时数据区&#xff09;Java 对象的创建过程&#xff08;五步&#xff0c;建议能默写出来并且要知道每一步虚拟机做了什么&#xff09;对象的访问定位的两种方式&#xff…

Java语言基础及java核心

一、Java语言特点 1、 简单 2、 面向对象 3、 分布式 4、 健壮 5、 安全 6、 中性架构跨平台 7、 超强的可移植性 8、 高性能 9、 多线程 二、java的环境变量 JAVA_HOMEC:\Program Files\Java\jdk1.8.0_101 &#xff08;到你的安装目录下&#xff09; CLASSPASH./ &#xff0…

移动端日期选择插件rolldate

rolldate为上一版jquery移动端时间插件的全新版本&#xff0c;目前保留了上一版的大部分功能&#xff0c;并且增加了回调函数&#xff0c;以及主题风格选取&#xff0c;最重要的是解决了上一版本的遗留问题&#xff0c;依赖jquery、滑动不够流畅、参数设计不够合理等等。开发日…

服务器如何查看gpu型号,linux 查看服务器gpu

linux 查看服务器gpu 内容精选换一换本节操作介绍通过华为云APP连接Linux实例的操作步骤。云服务器状态为“运行中”。已获取Linux云服务器用户名和密码&#xff0c;忘记密码请参考在控制台重置云耀云服务器密码重置密码。云耀云服务器已经绑定弹性公网IP。所在安全组入方向已开…

echarts vue 柱状图实例_VUE中使用Echarts绘制柱状图

在main.js中引入echartsimport echarts from ‘echarts‘Vue.prototype.$echarts echarts在相应的vue中导入echartsimport echarts from ‘echarts‘;实现柱状图显示mounted: function () {// 基于准备好的dom&#xff0c;初始化echarts实例let myChart echarts.init(documen…

从计算机体系结构方面思考深度学习

今年 1 月&#xff0c;谷歌人工智能负责人 Jeff Dean&#xff08;当时还是谷歌大脑负责人&#xff09;与 2017 年图灵奖得主、体系结构巨擘 David Patterson&#xff08;当时获奖结果尚未公布&#xff09;联合发表了题为《计算机体系结构黄金时代&#xff1a;赋能机器学习革命》…

使用Apollo通过WebSocket通过STOMP轻松进行消息传递

在我以前的文章中&#xff0c;我介绍了几个有趣的用例&#xff0c;这些用例使用著名的消息代理HornetQ和ActiveMQ通过Websockects实现STOMP消息传递。 但是我没有介绍的是Apollo&#xff0c;因为我个人认为它的API是冗长的&#xff0c;并且不像Java开发人员那样表现力强。 尽管…

h5渲染性能一瞥

内容来源&#xff1a;2018 年 6 月 30 日&#xff0c;饿了么前端主管向勇在“饿了么技术沙龙・第27弹 【前端专场】”进行《h5渲染性能一瞥》演讲分享。IT 大咖说&#xff08;微信id&#xff1a;itdakashuo&#xff09;作为独家视频合作方&#xff0c;经主办方和讲者审阅授权发…

爬虫系列之requests

爬取百度内容&#xff1a; 1 import requests2 url "https://www.baidu.com"3 4 if __name__ __main__:5 try:6 kv {user-agent: Mozilla/5.0}7 r requests.get(url, headerskv)8 r.raise_for_status() #返回状态值&#xff0c;如果…