最近碰到两个问题:javascript
而后点击浏览器“后退”按钮就直接返回到首页,实际这里想要的效果是返回列表页上一页。java
代码以下,在页数变化的时候,去异步请求数据,渲染页面。ajax
const currentChange = (currentPage) => { ajax(`请求地址/${currentPage}`) .then(renderPage) }
通过几番搜索,发现能够用History 接口来实现咱们想要功能。浏览器
按指定的名称和URL(若是提供该参数)将数据push进会话历史栈,数据被DOM进行不透明处理;你能够指定任何能够被序列化的javascript对象。具体描述能够参考 文档
经过history.pushState(state, title, url)能够修改会话历史栈,把咱们须要保存的数据存到state中,这里咱们存入一个对象,属性为当前页数;title通常没什么用,这里传入null;url会修改当前历史纪录的地址,浏览器在调用pushState()方法后不会去加载这个URL异步
假设当前currentPage为1,当前url为www.example.com/search/index优化
... const pushState = () => { const url = `/search/index/${currentPage}` history.push({ page: currentPage }, null, url) } const currentChange = (currentPage) => { ajax(`请求地址/${currentPage}`) .then(res =>{ pushState(currentPage) renderPage() }) } ...
如今代码执行顺序是:页数改变 => ajax请求 => pushState => renderPage()
在pushState以后当前url变成www.example.com/search/index/1url
如今咱们经过history.pushState()方法把状态存入历史会话中了,接下来就要监听window.onpopstate事件spa
参考mdn文档 window.onpopstate每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发. code
调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 好比点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法).对象
接下来监听这个事件
window.addEventListener("popstate", (event) => { if(event.state !== null){ page = event.state.page changeCurrentPage(page) // 修改当前页数 } })
当popstate触发时,会修改当前页数,而后触发以前定义的currentChange方法,更新数据,渲染页面。
到此为止,问题1就解决了。
接下来要解决问题二:从详情页返回列表页,记住以前的状态
这里我用url来记录状态,以前pushState推入的url就派上用场了。
只要把进入页面首次请求的地址改为当前url就能够了
假设以前push的url为www.example.com/search/index/5,从详情页返回以后url还会显示www.example.com/search/index/5
mounted () { ajax(location.href) }
这样就完成了。固然若是你的状态比较复杂,能够把数据存入本地Storage,添加一些判断便可