History API

History API
遍历浏览器历史的可以使用history.back()\history.forward()\history.go(n)
判断历史页面的数量可以使用window.history.length
增加和修改history实体使用history.pushState(state,title,URL)\history.replaceState() ,replace就是修改当前的URL和状态并不新添加历史实体。
参数依次为保存的状态对象, 状态的title(通常可以设置为''),URL\hash的应显示的地址(optional).这些新的URL必须是与当前页面同源的。
state可以是任何可以序列化的对象,但是大小一定要限制在640k 字内,超出就要产生异常了,此时可以使用sessionStorage或者localStorage。
URL新的历史实体的URL
title是当前history实体的title
 
在浏览器崩溃或者重启之前设置了history.state对象。一旦再次启动浏览器的时候加载那个页面,就可以通过history.state 访问到上次popstate改变的对象。通常history.state一般是获取当前历史实体的状态。
 
pushState不会引起hashchange事件的触发 即便是新的URL与旧的URL只是hash的不同。
 replaceState是修改当前的history entry并不是添加新的。
  
这个API看上去很简单,需要知道的就是什么时候使用为什么使用它。
pushState方法可以在不刷新页面的情况下改变页面的URL,在一些特殊的细节需要的时候
这个很方便。比如页面的URL和页面的内容是不一样的时候,也就是说一个页面加载了其他页面的
内容,但是地址栏中的URL还是第一个page的而内容是第二个page的,这就引起了添加书签
时的疑惑
这个API通常是解决不同页面之间的来回切换的问题,同时也是用来在当前页面不变,而其状态之间来回切换的问题。
比如说,你用JavaScript修改了页面的一部内容而不是向服务器请求的新的页面,这样在浏览器的history里
是不会有新的实体记录加入的。一旦我们点击了回退按钮,并没有回到之前的页面状态,而是回到了之前的网站。
这里,我们看到后退的问题包含两部分:后退的URL路径和后退的状态。
后退的URL路径也就是更新页面URL的问题
后退的状态就是页面历史状态的问题
解决这个问题需要location.hash和hashchange来配合了
 location.hash指定URL路径#后面的部分(可以用来存储数据,但是只能是字符串),触发hashchange事件来进行状态的恢复变更。 
 
<script>
var times = 0;
 
function doclick() {
times++;
location.hash = times;
document.getElementById('message').innerHTML =
'Recorded <b>' + times + '</b> clicks';
}
//location.hash变化的时候,相应的页面状态也要更新,so 监听这个事件 
window.onhashchange = function() {
//实际上就是字符串的长度 
if (location.hash.length > 0) {
times =
parseInt(location.hash.replace('#',''),10);
} else {
times = 0;
 
}
document.getElementById('message').innerHTML =
'Recorded <b>' + times + '</b> clicks';
}
 
</script> 
<div onclick="doclick();">Click Me</div>
<div id="message">Recorded <b>0</b> clicks</div>
 把所有需要的数据放在字符串里会导致URL过长,存取数据不方便。所以更好的解决办法就是把hash作为key,然后
从某些缓存中获取页面保留的状态信息。 html5提供了办法就是history.pushState()以及popstate(),来存放和加载复杂的对象。
 <script>
var state;
function init() {
state = {
undonum: 0,
content: document.getElementById('content').innerHTML
};
}
function save() {
state.undonum++;
state.content = document.getElementById('content').innerHTML;
// 这个使得URL地址栏显示第三个参数指定的地址,ex.http://localhost:9000/#undo4
//并不会引起浏览器加载新文件或者检查文件及描点在不在 
history.pushState(state,'','#undo'+ state.undonum);
}
function popState(event) {
if (event.state) {
//用事件中的state换掉外部的state变量,在不是最初加载的情况下 
//在页面是这个URLhttp://localhost:9000/#undo16的时候,你后退 触发这个事件event.state就是http://localhost:9000/#undo15
state = event.state;
document.getElementById('content').innerHTML = state.content;
} else{
  //第一次加载的时候,用最初的state替换掉事件里的state
history.replaceState(state, '', '#undo' + state.undonum);
};
}
 </script>
<button onclick="save();">Save</button>
<button onclick="history.go(-1);">Undo</button>
 
window.onload = init;
window.onpopstate = popState;
window.onpageshow = popState;
 onpopstate和onpageshow应该都加上,主要是在页面最初加载没有状态要设置的时候,火狐不会触发popstate事件,其他浏览器可以。
 
 彩蛋
对于页面的恢复:
可以用创建额外的页面来满足URL的更改,但推荐使用server-side include和客户端模板。
posted @ 2015-09-23 13:44  js渣渣  阅读(351)  评论(0)    收藏  举报