文档章节

浅谈浏览器历史记录

放开那个女孩
 放开那个女孩
发布于 2017/08/28 14:26
字数 1434
阅读 17
收藏 0

为什么要研究浏览器历史记录,更加深入的了解单页面应有的路由

一、基本概念

  1. 浏览器历史记录管理栈
  2. 栈中的指针指向当前页面
  3. 如何生成一条历史记录
    1)点击页面中有a标签的href
    2)执行location.href = 'xxx'(location.replace('xxx')生成一条记录取代当前指针所指向的记录)
    3)表单提交跳转(注意只能跳到当前窗口)
    4)简单粗暴的方法,直接在当前页面的地址栏中输入地址
    5)使用pushState方法可以不刷新页面就可以生成一条历史记录,页面URL发生改变
    简言之,只要当页面的URL改变时,就会生成一条历史记录。在IE8及更高的版本中、Opera、Firefox、Chrome、Safari3及更高的版本中改变hash也会生成一条历史记录。
  4. 如何在浏览器中获取当前页面的历史记录状态
 

window.history

如下图所示

length:1 // 表示当前页面中会话历史元素的数目,当打开一个标签页时就会自动生成一个历史记录

scrollRestoration:"auto" // 允许web应用程序在历史导航上显示的设置默认滚动恢复行为。此属性可以是自动的(auto)或者是手动的(manual)。

这是一个实验的属性,在IE和Safari下不支持。

state:null // 返回一个表示历史堆栈顶部的状态的值。这是一种可以不必等待popstate事件而查看状态的方式。

指针指向的记录如果state不为null,则显示存进去的state。

history对象

二、浏览器对历史记录的管理策略

每次增添的历史记录都会在栈的最顶端,以谷歌浏览器为例
1)点击打开浏览器的标签页,此时生成一条历史记录,并打开测试页面进行测试。每打开一个页面都会生成一条历史记录,新历史记录压人栈顶。
测试的时候一定要在当前页打开页面。测试代码如下:

 

<div>

<a href="demo1.html">demo1</a>

</div>

<div>

<!--通过location.href="demo2.html"改变页面地址:-->

<button type="button" onclick="changTo(2);">href="demo2.html"</button>

</div>

<div>

<form action="demo3.html" method="get" class="dib"><button type="submit" >demo3.html</button></form>

</div>

<div>

<!--通过pushState来改变页面地址:-->

<button type="button" onclick="push4()">pushState"demo4.html"</button>

</div>

 

js代码如下:

 

function changTo(index) {

location.href = 'demo' + index + '.html';

}

function push4() {

history.pushState('hello', '', '/demo4.html')

}

 

点击demo1,demo2,demo3,demo4,然后再点击demo3,demo2,demo1生成的历史记录如下图
测试生成history对象

2)使用history API操作栈指针来获取历史页面

指针所在的位置会获取当前页面的state,
history.back() : 返回上一页
history.forword() : 跳转到前一页
history.go(n) : n可以为正数也可为负数,代表当前指针是向前移动还是向后移动几个位置。如果n大于或小于历史记录的数目时,指针不会发生任何变化。

下面图片的操作步骤为:先back() => go(-2) => go(-2) => go(2)
后退前进history指针变化

3)如果此时在demo3的位置点击demo1,历史记录栈会如下所示:
历史记录都是插入在栈指针所在位置的后面,前面的记录会被自动删除
后退前进history指针变化

4)历史记录超过了浏览器限制的最大条数(比如chrome、firfox为50条,IE超过了100),栈顶进入一条历史记录,则栈的底端移出去一条。

三、单页面应用中如何实现路由切换

目标:切换页面
异步传参

先介绍实现这种的两种方法:

HTML5推出的history API

三种方法:pushState replaceState onPopState

  1. pushState(state, title, URL)
    1). state: 代表一个Javascript对象,在创建对象的时候设置,可以在onpopstate和history对象中获取。(we impose a size limit of 640k characters on the serialized representation of a state object.)
    2). title: Firefox目前忽略这个参数,你可以给你的state设置一个小标题
    3). URL: 压人记录栈中URL,可选,不指定则视为当前URL。

    * 当执行pushState这个方法的时候不会去加载这个URL,但是会改变地址栏中的url。当重新加载这个页面时,URL是push进去的参数。
    * URL必须是同源链接
    
  2. replaceState(state, title, URL)参数和pushState一样,会替代当前指针指向的历史记录

  3. onPopState: 当指针在历史记录栈中已有的位置上移动时会触发,且指定的地址仍然在当前dom中。pushState和replaceState的操作不会触发这个事件
    MDN解释:

 

A popstate event is dispatched to the window every time the active history entry changes between two history entries for the same document.

The popstate event is only triggered by doing a browser action such as clicking on the back button (or calling history.back() in JavaScript).

And the event is only triggered when the user navigates between two history entries for the same document.

生成一条历史记录

1

window.history.pushState('{key: 1586}', '', '/demo1.html')

切换页面

1

2

3

4

window.addEventListener('popstate', e => {

const obj = e.state // 可获取栈指针指向的记录state

// dosometing

})warntext

异步传参

可根据state来传参

根据hash实现,hashchange来捕捉路由的变化

生成一条历史记录

 

getHash (): string {

// We can't use window.location.hash here because it's not

// consistent across browsers - Firefox will pre-decode it!

const href = window.location.href

const index = href.indexOf('#')

return index === -1 ? '' : href.slice(index + 1)

}

function pushHash (path) {

window.location.hash = path

}

function replaceHash (path) {

const i = window.location.href.indexOf('#')

window.location.replace(

window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path

)

}

切换页面

hashchange监听后退和前进操作

1

2

3

window.addEventListener('hashchange',function(){

// dosometing

})

 

异步传参

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function getParams(){

var hashArr = location.hash.split("?"),

hashName = hashArr[0].split("#")[1],//路由地址

params = hashArr[1] ? hashArr[1].split("&") : [],//参数内容

query = {};

for(var i = 0;i<params.length ; i++){

var item = params[i].split("=");

query[item[0]] = item[1]

}

return {

path:hashName,

query:query

}

}

本文转载自:https://x-front-team.github.io/2016/11/28/浅谈浏览器历史记录/

共有 人打赏支持
放开那个女孩
粉丝 3
博文 112
码字总数 43036
作品 0
杭州
程序员
私信 提问
浅谈移动端页面无刷新跳转问题的解决方案

浅谈移动端页面无刷新跳转问题的解决方案 2017-12-22 祈澈姑娘 最近开发微信公众号,用的框架是 一般的 UI,但是涉及到多页面之间的相互跳转的问题,降低了浏览器的性能,用户体验特别不好,...

祈澈姑娘
2017/12/22
0
0
目录帖:​​​​​​​浅谈算法和数据结构

浅谈算法和数据结构: 一 栈和队列 浅谈算法和数据结构: 二 基本排序算法 浅谈算法和数据结构: 三 合并排序 浅谈算法和数据结构: 四 快速排序 浅谈算法和数据结构: 五 优先级队列与堆排序 浅谈...

安小乐
2018/09/04
0
0
浅谈http协议

1.http基础概念 2.请求与响应过程 3.请求头响应头及请求方式简述 4.客户端缓存(cookie,session及其他缓存机制) 1.什么是http???? HTTP是一套计算机通过网络进行通信的规则。使HTTP客户(如...

Evan_zhan
2018/01/14
0
0
浅谈MYSQL之日志文件系统

同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分。MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等。这些日志可以帮助我们定位m...

無言地对白
2018/01/03
0
0
浅谈Facebook的服务器架构(组图)

导读:毫无疑问,作为全球最领先的社交网络,Facebook的高性能集群系统承担了海量数据的处理,它的服务器架构一直为业界众人所关注。CSDN博主yanghehong在他自己最新的一篇博客《 Facebook的...

Yisen
2011/06/11
4
0

没有更多内容

加载失败,请刷新页面

加载更多

ToolBar控件在C#开发APP中的使用方式【附案例源码】——Smobiler移动开发平台

控件说明 底部工具栏控件。 效果演示 其他效果 该界面为仿淘宝UI制作的一个简单的UI模板,源码获取方式请拉至文章末尾。 特色属性 属性 属性说明 Direction(相对布局) 容器主轴方向。 Flex...

amanda112
18分钟前
0
0
模块

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等...

gtandsn
24分钟前
1
0
代码之外的生存指南,这6本书助你提升软实力

上期盟主向大家推荐了6本技术类书籍,引起了热烈反响。那么,工作之余,还有哪些好书能够为你打开更多的精彩世界呢?本期,多位知名企业的技术大咖将继续为您带来好书推荐,在新的一年里,为...

安卓绿色联盟
27分钟前
3
0
5分钟用Jitpack发布开源库

作者: 菜刀文 Demo:https://github.com/helen-x/JitPackReleaseDemo 项目开发中会用到很多开源库, 他们一般通过Maven/Gradle依赖进来的. 演而优则唱,开发越来越溜以后, 你是否也蠢蠢欲动,想发...

SuShine
33分钟前
2
0
状态码 301 与 302的区别

302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。 而301重定向是永久的重定向,搜索引擎在抓取新的内容的同...

小草先森
39分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部