html5新特性之history

history

history对象是用来记录浏览器访问历史的,可以将其理解为保存了一个有序列表的对象,每个对象都代表了一个页面信息(包括url、title等)。同时history也提供了back()forward()go()等方法来实现页面的切换,等同于浏览器本的前进/后退按钮的操作。

history中记录了浏览器窗口访问过的url,但是出于安全考虑,浏览器禁止通过程序获取 history 中的具体信息,只能通过length属性来获取 history 中的记录数,通过back()forward()go()方法进行页面切换。

html5的新特性

html5为 history 引入了 pushState 和 replaceState 两个方法,这两个方法用来更新 history 对象中的列表信息。

此外还提供了一个事件window.onpopstate,通过浏览器动作修改 history 对象信息会触发该事件,比如用户点击前进/后退按钮。pushState 和 replaceState 两个方法不会触发window.onpopstate事件。

pushState

pushState方法有三个参数:

  1. 第一个参数是个对象,可以在onpopstate事件中通过event.state获取到,也可以在页面中通过history.state获取到。
  2. 第二个参数是个字符串,用来设置页面的 title。
  3. 第三个参数是个字符串,就是保存到 history 中的 url 。

下面是一个完整的html文件,文件名为demo.html。 把该文件放到web服务器上,从浏览器访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>

<body>
<button onclick="doPushState()">pushState</button>
<button onclick="count()">count</button>

<script>
var index = 1;
console.log(history.state);
window.onpopstate = function () {
console.log(event.state);
};

function doPushState() {
history.pushState({ a: "123123" }, "newtitle", "test" + (index++) + ".html");
// if (index === 2) {
console.log(history.state);
// }
}

function count() {
alert(window.history.length);
}
</script>
</body>

</html>

页面首先会执行 $()方法,弹出代码中的location.href信息。 这时执行count按钮,显示为1,注意如果在ie或chrome的新的浏览器窗口打开,值可能为2,因为它们的窗口会加载系统默认的一个页面,不是一个空白的窗口。这时我们每点击一下pushState按钮,发现浏览器的地址会发生变化,先后变为test1.html , test2.html, test3.html, …….,并且通过点击count按钮发现,弹出的值加1. 这说明每调用一次pushState方法,history中就会新增加一条url记录。

但是,pushState 与普通的打开一个新页面不同。浏览器不会在调用pushState()方法后加载这个url,也就是说即使你写一个错误的url,也不会报错。pushState只是将一个记录添加进了 history 列表,并不去加载。

replaceState

replaceState 方法和 pushState 方法有相同的三个参数,区别在于 replaceState 是用来修改 history 对象中记录的当前页信息,而不是新建。

onpopstate

window对象的popstate事件,当进行页面的前进或回退时,会触发该事件,并且在事件响应函数中通过 history.state 或者 event.state 可以获取到 pushState方法和replaceState方法中第一个参数指定的对象。

应用

现代新的前端框架都提供了基于 history 新特性的客户端路由。

在传统的 ajax 项目中,可以实现不需要刷新整个页面就可以进行局部页面的更新,但是无法通过前进/后退按钮回到操作前的页面,通过 history 新特性可以解决这个问题。