理解浏览器历史记录(2)- hashchange、pushState

574 查看

本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变化对浏览器的历史记录也会影响,同时锚点的变化跟pushState也有一些关联。所以就花了点时间,把这两个东西尽量都琢磨清楚。本文记录相关的一些要点及研究过程。

1. hashchange

这个部分的内容也已经补充到上文的最后了,这里只是细化一下。总的结论是:如果一个网页只是锚点,也就是location.hash发生变化,也会导致历史记录栈的变化;且变化相关的所有特性,都与上文描述的整个页面变化的特性相同。常见的改变网页锚点的方式有:

1)直接更改浏览器地址,在最后面增加或改变#hash;
2)通过改变location.href或location.hash的值;
3)通过触发点击带锚点的链接;
4)浏览器前进后退可能导致hash的变化,前提是两个网页地址中的hash值不同。

假如我们还用上文的demo来测试,并按照以下步骤操作的话:
打开新选项卡;输入demo1.html;在地址栏后面加#1;将地址栏#1改成#2;将地址栏#2改成#3;将地址栏#3改成#1。
那么历史记录栈的存储状态就应该类似下面这个形式:

459873-20161014155747562-1970766655

由于锚点变化也会在历史记录栈添加新的记录,所以history.length也会在锚点变化之后改变。每当锚点发生变化的时候,主流浏览器还会触发window对象的onhashchange事件,在这个事件回调里面,我们通过事件对象和location能够拿到很有用三个参数:

event.oldURL返回锚点变化前的完整浏览器地址;
event.newURL返回锚点变化后的完整浏览器地址;
location.hash返回锚点变化后页面地址中的锚点值。

借助于这三个信息,可以在hashchange回调内加一些控制器的逻辑,来实现单页程序开发里面关键的路由功能。现简单实现举例如下: