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方法有三个参数:
- 第一个参数是个对象,可以在
onpopstate
事件中通过event.state
获取到,也可以在页面中通过history.state
获取到。 - 第二个参数是个字符串,用来设置页面的 title。
- 第三个参数是个字符串,就是保存到 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
<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 新特性可以解决这个问题。