详解H5中的history单页面,手动实现单页面开发,细说h5单页面原理
就目前来看,前端的单页面开发占了很大一部分,一方面无刷新的切换增强了体验,并且浏览器记录依然存在,前进后退都没问题,在之前我们通地址栏中的hash改变来触发onhashchange方法来实现单页面应用,但是#的形式总是令人不爽,幸好h5新增了history.pushState与history.replaceState。
1.介绍API
history.pushState(data, title [, url]):
往历史记录堆栈顶部添加一条记录; data会在onpopstate事件触发时作为参数传递过去,title为页面标题,当前所有浏览器都会 忽略此参数(我们在自己实现的时候可以随便填写),url为页面地址,就是如果history.pushState({name:'home'},'home page' ,'home')则地址栏就成了/home,更神奇的是此时不会向后端发送请求,仅仅是url改变。
history.replaceState(data, title [, url]) :
更改当前的历史记录,参数跟history.pushState(data, title [, url])一致,只不过不会像浏览器历史栈添加数据,而是替代之前的历史记录;
history.state:用于存储以上方法的data数据,
window.onpopstate:响应pushState或replaceState的调用;
2.介绍实现单页面原理
通过以上几个方法我们完全可以改变url并且监听到url的变化,比如url由localhost:8000改变成localhost:8000/home,此时我们通过onpopstate监听到了这个变化,并且拿到data数据,假设拿到了name,此时假设有以下对应路由表,其实可以随便定义,
let route = {
home:{
name:'home',
url:'./home.html',
des:'home page'
},
class:{
name:'class',
url:'./class.html',
des:'class page'
}
}
那我们就知道此时home对应应该是./home.html,于是我们利用ajax将./home.html加载过来,此时我们拿到了home.html的所有信息,于是跟vue或者其他框架一样挂载到当前页面的一个元素上。
注意点:
我们主动 利用history.pushState({name:'home'},'home page' ,'home')时候并不会触发onpopstate,就是说此时是无法知道url变动了,为了让页面顺利跳转又触发我们提供的ajax,那么我们就要修改一下history.pushState
var pushState = history.pushState; // 存储原生 replaceState
history.pushState = function(state, param) { // 改写 replaceState
var urlName = arguments[2];
var url = route[urlName].url;
ajax(url)
return pushState.apply(history, arguments); // 调用原生的 replaceState
};
如上,我们不仅在使用 history.pushState时候,触发我们自己定义的ajax函数,加载了页面,又调用了原生的方法,是不会影响原生历史记录和跳转等问题。
现在我们知道我们每次调用history.pushState都会触发ajax函数
<div id="app"></div> <script>
function ajax(url){
//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端
ajax.open('get',url);
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
if (ajax.readyState==4 &&ajax.status==200) {
//步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
//输入相应的内容
document.querySelector('#app').innerHTML = ajax.responseText
}
}
}
<script>
利用这个ajax就可以将别的页面的内容加载到本页面的#app这个元素上,实现了单页面跳转。
3.需要注意的地方和坑:
1.在尝试该方法前,需要其启动服务器代理html文件,即静态的html文件打开会报错
2.我们在通过history.pushState改变url浏览器并不会跟处理普通url一样新发送请求,但是我们在刷新的时候浏览器还是会发送请求,即localhost:8000/home刷新浏览器就会请求这个接口,就会导致后台根本没有这个路由返回404,(这也是vue-route经常会出现刷新404问题的原因)解决办法就是遇到404的都代理给index.html,我测试使用express来起服务的,有一个插件叫 connect-history-api-fallback,使用之后就不会出现这个问题。
如果有想要自己尝试的,这里附上我们demo:https://github.com/jiangzhenfei/h5History,下载还只要执行node server.js即可,打开浏览器就可以尝试了。
详解H5中的history单页面,手动实现单页面开发,细说h5单页面原理的更多相关文章
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- 详解Android中的四大组件之一:Activity详解
activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...
- jQuery:详解jQuery中的事件(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...
- 详解 SWT 中的 Browser.setUrl(String url, String postData, String[] headers) 的用法
http://hi.baidu.com/matrix286/item/b9e88b28b90707c9ddf69a6e ———————————————————————————————————————— ...
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- 详解javaweb中jstl如何循环List中的Map数据_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 详解javaweb中jstl如何循环List中的Map数据 第一种方式: 1:后台代码(测试) List<Map& ...
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
- (数据科学学习手札140)详解geopandas中基于pyogrio的矢量读写引擎
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,前不久我在一篇文章中给大家分享 ...
- 图文详解Unity3D中Material的Tiling和Offset是怎么回事
图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
随机推荐
- JarvisOJ平台Web题部分writeup
PORT51 题目链接:http://web.jarvisoj.com:32770/ 这道题本来以为是访问服务器的51号端口,但是想想又不太对,应该是本地的51号端口访问服务器 想着用linux下的c ...
- Web服务器负载均衡的几种方案 : DNS轮询
本篇主要讲一下最简单的方案——DNS轮询. DNS轮询 大多域名注册商都支持多条A记录 的解析,其实这就是DNS轮询 ,DNS 服务器 将解析请求按照A记录 的顺序,逐一分配到不同的IP上,这样就完成 ...
- centOS 中安装 Redis
之前安装过了 jdk,mysql,tomcat,这次安装 Redis,最开始是将 redis 安装在 windows 下 run 的,这时安装在 Linux 里面试试. 1 . 首先得安装 c环境,用 ...
- Spring Autowired原理
今天来整理一下Spring的自动装配 autowire一节,在这里我们要解决以下问题: 什么是自动装配? 自动装配的意义? 自动装配有几种类型? 如何启用自动装配? 自动装配将引发的问题? 一.什么是 ...
- 使用JMeter代理录制app测试脚本
准备条件:JMeter.手机app 上一篇介绍过录制Web测试脚本的方式有两种,使用代理和使用第三方工具.本篇录制app测试脚本只讨论使用代理的方式,其他方式以后有机会再补充.其实Web和app使用代 ...
- 迁移数据到历史表SQL(转)
有时工作需要需要把当前表的数据,移到历史表中,而历史表基本是以时间(年)为后缀来命名历史表的,如 A_2011,A_2012,在移数据时,要按数据的时间,移到不同的表中,且由于如果数据有同步.一次处理 ...
- 🔺 Garbage Remembering Exam UVA - 11637()
题目大意:给你N个单词,有两种方法随机排列,一种随机排成一行,另一种随机排成一圈,当两个单词之间的距离在两种排列中都严格小于K时,则这两个单词构成无效单词,问无效单词的期望. 解题思路:首先对于一排单 ...
- mysql安装使用详细教程
1.数据库存储数据的方式与Excel类似. 一.数据库介绍 1.什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访 ...
- 【刷题】BZOJ 1951 [Sdoi2010]古代猪文
Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久 ...
- [CF1111E]Tree
题目大意:给一棵$n(n\leqslant10^5)$个点的树,有$q(q\leqslant10^5)$次询问,每次询问给出$k,m,r$表示把以下$k$个点分成不超过$m$组,使得在以$r$为根的情 ...