单页面应用实现浏览器前进后退的方法

Ajax可以在不需要页面的刷新动作时获取数据(页面的URL也会保持不变),但是问题时,这样也就无法通过浏览器进行前进与后退操作。

现在这个问题可以通过history.pushState()方法以及window.onpopstate事件监听去解决。

history.pushState()用法

history.pushState()方法可以无刷新地向当前history插入一条历史状态。

语法:

1
history.pushState(stateObject, title, url);
  • stateObject:传入的状态对象。当前进(后退)到某一新的状态时,会触发popstate事件。此事件对象event.state存储的就是这个stateObject的值
  • title:新状态的标题(目前,大多数浏览器并不支持该参数,建议传null值)
  • url:状态对应的历史记录的地址

window.onpopstate事件监听

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

  • History.go()
  • History.back():等同于history.go(-1)
  • History.forward():等同于history.go(1)

实例:

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}

实例

现在有一个报表应用用于展示某年的销售数据。

  1. 刚打开时,没有任何报表数据:

2015 2016 2017 2018

一季度 二季度 三季度 四季度 总和

此时的URL: http://example.com/getFinaData.php

  1. 点击按钮通过Ajax加载2015年的数据

2015 2016 2017 2018

一季度 二季度 三季度 四季度 总和
122万 147万 135万 153万 557万

同时我们为这一次数据加载新增一条历史状态

1
history.pushState({year: 2015}, "页面标题", "getFinaData.php?year=2015");

此时的URL变为:http://example.com/getFinaData.php?year=2015

同时你会发现浏览器的后退按钮激活了,因为在pushState()的作用下无刷新地新增了一条历史状态。

  1. 重复上一步,我们再为这一次数据加载新增一条历史状态:
1
history.pushState({year: 2018}, "页面标题", "getFinaData.php?year=2018");

此时的URL变为:http://example.com/getFinaData.php?year=2018

  1. 现在,我们使用后退键,看看会发生什么?

URL重新变回:http://example.com/getFinaData.php?year=2015

但是,界面并没有发生变化(表格依旧显示的是2018年的数据)

因为点击后退键只是简单地切回到上一个状态,而这个状态是无刷新的,我们要做的捕获这个切换到的状态,并获取上一次保存的状态值(pushState()的第一个参数),然后再调用一次ajax请求数据。

1
2
3
4
5
6
7
8
window.onpopstate = function(event) {
// 获取存储的状态
var params = event.state; // {year: 2015}

// 根据存储的状态,再次使用Ajax加载数据并插入到视图中

// ...具体代码省略
};

现在,成功实现无刷新后退到上一次界面。

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道