我们可以使用location.hash来模拟ajax的前进后退功能。但是使用location.hash存在下面几个问题:
1.使用location.hash会导致地址栏的url发生变化,用户体验不够友好。
2.location.hash产生的历史记录无法修改,每次hash改变都会导致产生一个新的历史记录。
3.location.hash只是1个hash字符串,不能存储很多状态相关的信息。
为了解决这些问题,HTML5中引入了history.pushState()、history.replaceState()、popstate事件来处理浏览器历史记录的问题。我们可以通过上诉方法实现改变地址栏url 的参数,实现页面不会刷新,但是页面上的数据实现更新。
1. history.state:
当前URL下对应的状态信息。如果当前URL不是通过pushState或者replaceState产生的,那么history.state是null
。
2. onpopstate 可以监听 state 的变化:
history.go 和 history.back(包括用户按浏览器历史前进后退按钮)触发,并且页面无刷的时候(由于使用pushState修改了history)会触发popstate事件,事件发生时浏览器会从history中取出URL和对应的state对象替换当前的URL和history.state。通过event.state也可以获取history.state。
window.onpopstate = function(event){
if(history.state) {
console.log( '当前state:' event.state ); // { key:1}
console.log( 'url:' document.location ); // http://...?key=1
}
}
3. history.pushState(state, title, url) :
将当前URL和history.state加入到 history 中,并用新的state和URL替换当前。不会造成页面刷新。
state:与要跳转到的URL对应的状态信息。
title:一般传空字符串 或 null 即可。
url:要跳转到的URL地址,不能跨域。
function addHistory(id){
window.history.pushState({"id":id},"","?key=1");
}
//添加并激活一个历史记录条目 http://...?page=1, 条目索引为1
history.pushState({page: 1}, “title 1”, “?page=1”);
//添加并激活一个历史记录 http://...?page=2, 条目索引为2
history.pushState({page: 2}, “title 2”, “?page=2”);
4.history.replaceState(state, title, url) :
用新的state和URL替换当前。不会造成页面刷新。
state:与要跳转到的URL对应的状态信息。
title:一般传空字符串 或 null 即可。
url:要跳转到的URL地址,不能跨域。
//修改当前激活的历史记录 http://...?page=2 变为 http://ex..?page=3, 条目索引仍旧为2
history.replaceState({page: 3}, “title 3”, “?page=3”);
5. 可以通过监听 pushState 和 replaceState 行为实现拦截 :
window.addEventListener('replaceState', function(e) {
console.log('replaceState');
});