HTML5中history提供的pushStatereplaceState这两个API。它们提供了操作浏览器历史栈的方法。

pushState能够在不加载页面的情况下改变浏览器的URL。这个方法接受三个参数:

状态对象新状态的标题可选的相对URL。

 history.pushState(data, null, '#/page=1');
pushState接收3个参数,第一个参数为一个obj,表示浏览器的state属性
第二个参数是document.title的值,一般设定为`null`;
第三个参数string,用以改变当前url

pushState方法在改变url的同时向浏览器历史栈中压入新的历史记录

接收url的参数为string类型,用以改变当前地址栏的url.需要注意的一点就是这个参数不能和跨域,即协议,域名,端口必须都是相同的,如果出现跨域的情况,即会提示:

Example:

其中 replaceState:

  replaceState接收的参数pushState相同,但是最终的效果是:地址栏url会根据接收的参数而变化,但是浏览器并未在当浏览历史栈中增加浏览器的历史记录,而是替换当前的浏览器历史记录。

通过pushStatereplaceState虽然能改变URL,但是不会主动触发浏览器reload

window对象还提供 popstate方法

这个方法用以监听浏览器在不同历史记录中进行切换,而触发相应的事件

在浏览器提供的history对象上还有goback方法,用以模拟用户点击浏览器的前进后退按钮。在某个web应用当中,比如点击了<a>标签,发生了页面的跳转。这时调用history.back()方法后页面回退,同时页面发生刷新,这时window.onpopstate无法监听这个事件。但是如果是通过pushState或者replaceState改变URL不发生浏览器刷新的话,再使用history.back()history.go(),这样popstate事件会被触发

输出如下:

注意:  通过pushState在url上添加?page=1可以通过location.search去获取search的内容。不过如果通过location.search去改变url的话是会主动触发浏览器reload的。

API大致了解了,那么这些方法可以运用到哪些地方呢?一个比较常用的场景是就在单页应用中,通过这些API完成前端的路由设计,利用pushStatereplaceState可以改变url同时浏览器不刷新,并且通过 popstate 监听浏览器历史记录的方式,完成一系列的异步动作。

简单的路由如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
a {color: red;text-decoration: underline;}
</style>
</head>
<body>
<a data-href="/post">post</a>
<a data-href="/login">login</a>
<script>
const Router = [];
const addRoute = (path ='', handle=() =>{}) => {
let obj = {
path,
handle
};
Router.push(obj);
}
// 添加路由定义
addRoute('/post', function(){
// todo...
alert('/post');
})
addRoute('/login', function(){
// todo...
alert('login');
})
// 路由处理
const routeHandle = (path) => {
for(var item of Router){
if (item.path === path) {
item.handle.apply(null, [path]);
return true;
}
}
}
document.addEventListener('click', function(e) {
let dataset = e.target.dataset;
if(dataset) {
if(routeHandle(dataset.href)) {
var url = window.location.href;
history.pushState({route: dataset.href}, null, oriUrl + dataset.href);
//阻止默认行为
return false;
// e.preventDefault();
}
}
})
</script>
</body>
</html>

大致的实现思路就是,通过<a>添加路由信息,然后拦截<a>标签的默认行为,并与注册的路由信息进行匹配。若匹配成功调用对应的handle方法

前端路由的实现(三) —— History的pushState和replaceState用法的更多相关文章

  1. [Vue 牛刀小试]:第十二章 - 使用 Vue Router 实现 Vue 中的前端路由控制

    一.前言 前端路由是什么?如果你之前从事的是后端的工作,或者虽然有接触前端,但是并没有使用到单页面应用的话,这个概念对你来说还是会很陌生的.那么,为什么会在单页面应用中存在这么一个概念,以及,前端路由 ...

  2. 前端路由以及浏览器回退,hash & history & location

    一.前言 其实不止一次想监听浏览器的回退方法,比如 在 list.html 页滚动加载了几页列表,点到 detail.html 看详情,反回来时又得重新加载几页 H5 有背景音乐的,跳页就得重新放,体 ...

  3. 前端路由hash、history原理及简单的实践下

    阅读目录 一:什么是路由?前端有哪些路由?他们有哪些特性? 二:如何实现简单的hash路由? 三:如何实现简单的history路由? 四:hash和history路由一起实现 回到顶部 一:什么是路由 ...

  4. 前端路由两种模式:hash、history

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

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

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

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

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

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

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

  8. 前端路由原理之 hash 模式和 history 模式

    什么是路由? 个人理解路由就是浏览器 URL 和页面内容的一种映射关系. 比如你看到我这篇博客,博客的链接是一个 URL,而 URL 对应的就是我这篇博客的网页内容,这二者之间的映射关系就是路由. 其 ...

  9. Vue(三)之前端路由

    01-前端路由 1.前端路由的实现原理 vue+vue-router 主要来做单页面应用(Single Page Application) 为什么我们要做单页面应用? (1)传统的开发方式 url改变 ...

随机推荐

  1. JS数组 谁是团里成员(数组赋值)var myarray = new Array(66,80,90,77,59);//创建数组同时赋值

    谁是团里成员(数组赋值) 数组创建好,接下来我们为数组赋值.我们把数组看似旅游团的大巴车,大巴车里有很多位置,每个位置都有一个号码,顾客要坐在哪个位置呢? 第一步:组个大巴车 第二步:按票对号入座 大 ...

  2. Android开发 获取View的尺寸的2个方法

    前言 总所周知,在activity启动的onCreate或者其他生命周期里去获取View的尺寸是错误的,因为很有可能View并没有初始化测量绘制完成.你这个时候获取的宽或的高不出意外就是0.所以,我们 ...

  3. js怎样截取字符串后几位以及截取字符串前几位

    想要截取字符串前几位与后几位,主要代码如下 截取字符串前几位 var disName ='开心一族漂亮家园'; var shortName = disName.substring(0,5); cons ...

  4. Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试【转】

    Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试[转] 本文是本人前一段时间做一个简单Java监控工具调研总 ...

  5. 【转帖】WebRTC回声抵消模块简要分析

    webrtc 的回声抵消(aec.aecm)算法主要包括以下几个重要模块:回声时延估计:NLMS(归一化最小均方自适应算法):NLP(非线性滤波):CNG(舒适噪声产生).一般经典aec算法还应包括双 ...

  6. Python-线程(1)

    目录 什么是线程 进程与线程的区别 开启线程 为什么要使用线程 线程之间数据是共享的 什么是线程 线程与进程都是虚拟单位,目的是为了更好的描述某种事物 进程与线程的区别 进程:资源单位 线程:执行单位 ...

  7. 使用pageHelper分页查询,报sql语句错误

    1.异常详情:  2.异常分析: (1)pageHelper分页大致流程: 配置默认的拦截器:pagehelper.PageInterceptor,对发送的查询语句进行拦截,拦截之后对原有的查询语句进 ...

  8. js实现获取两个日期之间所有日期的方法

    function getDate(datestr){ var temp = datestr.split("-"); var date = new Date(temp[0],temp ...

  9. JVM基础总结

  10. Python实例2-逗号代码

    假定有下面这样的列表: spam = ['apples', 'bananas', 'tofu', 'cats'] 编写一个函数,它以一个列表值作为参数,返回一个字符串.该字符串包含所有表项,表项之间以 ...