DOM中的window对象通过window.history方法提供了对浏览器历史记录的读取,让你可以在用户的访问记录中前进和后退。从HTML5开始,我们可以开始操作这个历史记录堆栈。

1.window属性history的方法

使用back(),forward(),和go()方法可以在用户的历史记录中前进和后退

用户后退行为,这个方法会像用户点击了浏览器工具栏上的返回键一样。

1
window.history.back();


用户前进行为:
1
window.history.forward();

使用go()方法从session历史中载入特定的页面,当然,你可以前进或者后退多个页面。

1
2
//向后移动一页:
window.history.go(-1);

1
2
//向前移动一页:
window.history.go(1);

还可以通过检查浏览器历史记录的length属性来找到历史记录堆栈中的页面总数。

1
var numberOfEntries = window.history.length;

注意:IE支持向go()方法传URL参数。

2.添加和修改history实体

Html5引入了histtory.pushState()history.replaceState() 这两个方法,他们允许添加和修改history实体
同时,这些方法会和 window.onpopstate 事件一起工作。
使用history.pushState()方法来修改referrer,这种方法可以被用在经过修改状态后而为xmlhttpRequest对象创建的http header中,这个referrer会是创建XMLHttpRequest时document的URL。

pushState 用于向 history 添加当前页面的记录,而 replaceState 和 pushState 的用法完全一样,唯一的区别就是它用于修改当前页面在 history 中的记录。
假设 https://youku.com/foo.html 页面执行了下面的Js

1
2
var stateObj = { foo: "bar" };  
history.pushState(stateObj, "page 2", "bar.html");

这种方法将会使url地址栏显示https://youku.com/bar.html但浏览器不会加载bar.html页面,即使这个页面存在也不会加载。
现在再次假设用户继续访问https://tudou.com,然后点击后退。这时,url地址栏将会出现https://youku.com/bar.html,页面会得到popstate事件,这个状态对象会包含一个stateObj的copy。这个页面看起来像foo.html。
这时,我们再次点击后退,URL将变成 https://youku.com/foo.html,document将得到另一个popstate事件和为null的state对象,这次的返回动作并没有改变文档的内容。

pushState方法

pushState()有三个参数:state对象标题URL(可选)。具体细节:

state对象
state对象是一个JavaScript对象,它关系到由pushState()方法创建出来的新的history实体。用以存储关于你所要插入到历史,记录的条目的相关信息。State对象可以是任何Json字符串。因为firefox会使用用户的硬盘来存取state对象,这个对象的最大存储空间为640k。如果大于这个数 值,则pushState()方法会抛出一个异常。如果确实需要更多的空间来存储,请使用本地存储。

title[firefox]

未来可能会被使用上的一个参数,目前使用无实际的意义。现在最安全的使用方式是传一个空字符串,以防止将来的修改。或者可以传一个简短的标题来表示state。

URL

这个参数用来传递新的history实体的URL,注意浏览器将不会在调用pushState()方法后加载这个URL,但也许会过一会尝试加载这个URL。例如在用户重启了浏览器后,新的url可以不是绝对路径。如果是相对路径,那么它会相对于现有的url。新的url必须和现有的url同域,否则pushState()将抛出异常。这个参数是选填的,如果为空,则会被置为document当前的url。
某种意义上来说,调用pushState()方法很像设置了window.location = “#foo”,这两者都会创建和激活另一个关联到当前document的history实体,但pushState()另外有一些优点:

新的url可以是任何和当前url同域的url,相比之下,如果只设置hash,window.location会保持在同一个document。
如果不需要,你可以不修改url。对比而言,设置window.location = “#foo”;仅产生新的history实体,如果你当前的hash不是#foo
你可以将任意的数据与你的新history实体关联。使用基于hash的方法,需要将所有相关的数据编码为一个短字符串。

注意,pushState()方法不会使hashchange时间发生,即使是新旧url只是hash不同。

replaceState()方法
1
history.replaceState()

用起来很像pushState(),除了replaceState()是用来修改当前的history实体而不是创建一个新的。这个方法有时会很有用,当 你需要对某些用户行为作反应而更新一个state对象或者当前history实体时,可以使用它来更新state对象或者当前history实体的url。

popstate事件

调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法).
详见window.onpopstate

1
2
3
4
5
6
7
8
9
10
window.onpopstate = function(event) {
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
//绑定事件处理函数.
history.pushState({page: 1}, "title 1", "?page=1"); //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
history.pushState({page: 2}, "title 2", "?page=2"); //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2
history.replaceState({page: 3}, "title 3", "?page=3"); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3
history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back(); // 弹出 "location: http://example.com/example.html, state: null
history.go(2); // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}

欢迎交流转载请注明出处