资讯专栏INFORMATION COLUMN

使用history保存列表页ajax请求的状态

amuqiao / 3042人阅读

摘要:问题最近碰到两个问题从首页进入列表页之后,点击下一页的时候,使用请求更新数据,然后点击浏览器后退按钮就直接返回到首页,实际这里想要的效果是返回列表页上一页。没法记住之前分页状态。

问题

最近碰到两个问题:

从首页进入列表页之后,点击下一页的时候,使用ajax请求更新数据,

然后点击浏览器“后退”按钮就直接返回到首页,实际这里想要的效果是返回列表页上一页。

在列表页分页为2的页面进入详情页,然后点击“后退”按钮,返回的事列表页分页为1的页面。没法记住之前分页状态。

优化前代码


代码如下,在页数变化的时候,去异步请求数据,渲染页面。

const currentChange = (currentPage) => {
    ajax(`请求地址/${currentPage}`)
    .then(renderPage)
}
history

经过几番搜索,发现可以用History 接口来实现我们想要功能。

history.pushState()
按指定的名称和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/1

window.onpopstate

现在我们通过history.pushState()方法把状态存入历史会话中了,接下来就要监听window.onpopstate事件

参考mdn文档window.onpopstate 

每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发.

调用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方法,更新数据,渲染页面。

问题2

到此为止,问题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,添加一些判断即可

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92587.html

相关文章

  • vue 模仿今日头条demo

    vue 头条 demo 写在前面 总结一下写 demo 过程中 遇到的一些问题,方便自己的学习总结!如有错误,还请指正! 一直想学习使用 vue ,并准备以后在实际项目使用,之前跟着慕课网 黄轶 老师 敲了一下 饿了么商品购买页的demoele效果预览 该 demo 借鉴自 hcy1996-github 这个项目,但内部内容,布局风格,完全不同,只为共同学习,共同交流 数据接口 直接打开 今日...

    simpleapples 评论0 收藏0
  • HTML5 history API,创造更好浏览体验

    摘要:而唯一不引发刷新的参数并不会发送到服务器,因此服务器无法获得状态。目前建议设置为空字符串。此外请注意,及本身调用时是不触发事件的。我认为,按照渐进增强的思路,这样就是最好的了,也就是只使用较少的代码优化高级浏览器的使用体验。 HTML5 history API有什么用呢? 从Ajax翻页的问题说起 请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评...

    zgbgx 评论0 收藏0
  • Ajax局部面刷新和History API结合陷阱

    摘要:对于那些老网站或者老项目来说全盘改造成并不现实,于是就有了局部页面刷新这个解决方案。如果不知道局部页面刷新是何物请看这里,这里和这里。但实际上,第一次后退无法还原的内容陷阱,第二次后退页面刷新了一切恢复最初的样子。 ajax在现代网站已经得到非常普遍地应用,主要的好处大家都知道(异步加载数据,不用刷新整个浏览器,更小的数据传输尺寸)。对于那些老网站或者老项目来说全盘改造成ajax并不现...

    JasinYip 评论0 收藏0

发表评论

0条评论

amuqiao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<