如何在不刷新页面的情况下改变URL

问没有具体业务场景的技术问题都是耍流氓,那在回答这个问题之前先简单介绍一下业务场景。

下午6点半,小 H写了一个下午的代码揉揉眼睛伸个懒腰,「今天终于能早点回去了,先刷会知乎歇会」。突然,产品 小U一脸淫笑飘了过来,小 H 略感不妙。
『嗨嗨~ 你这工作状态不饱和啊,有个小需求来看看~。现在需要做一个新闻展示页,主功能区块分为新闻列表和分页两部分。很简单,两天能搞定吧~』小 U 说。
小 H 看了看原型稿,心想确实不难。点击分页时把直接把分页参数传递给后台,页面刷新后台直接返回渲染后的数据就行了,模板写的好的话甚至 js 都不需要了。正当小 H 开口准备说说技术实现时,被小 U 打断…
『不过为了体验好一些,在用户点下一页的时候别刷新页面』小 U 说。
『不刷新页面没关系,我用 ajax 可以实现,不过时间嘛…』小 H 略有所思
『果然是大牛啊,能实现我就放心了。时间好商量,不过这个项目特别急,晚上加加油啊』,说完小 U 就飘走了。
『cao, 看来又走不成了』小 H 嘀咕着。
两分钟后小 U 又跑了过来,『刚才忘了跟你说了,用户点了下一页后地址栏的地址要跟着变,这时候刷新页面还能定位到当前页』
『 🐎x10000~~~』

整理下需求:

  1. 点击分页页码可实现无刷新页面加载
  2. 同时 URL 在数据加载后会发生变化展示对应页码
  3. 刷新页面(带页码参数)会定位到当前页码
  4. 当点击返回时可会到上个页面

效果如Demo 所示。

对于第1条,我们可以使用 ajax 动态获取对应页码的数据。

对于第2条,我们可以使用 html5的 api「history.pushState」,用于改变 URL。

对于第3条,我们可以根据 URL 中页码参数获取对应页码的数据再做展示。

对于第4条,可以使用 「window.onpopstate」来监听返回事件

那history.pushState如何使用呢?比如当用户点击页码按钮时,可使用 ajax 获取对应页码的数据,拼装 DOM 放到页面上,然后调用下面的 setUrl 方法实现浏览器 URL 的更新。

function setUrl(page){
    var url = location.pathname + '?page=' +  page
    history.pushState({url: url, title: document.title}, document.title, url)
}

history.pushState() 带有三个参数:一个状态对象,一个标题(现在被忽略了),以及一个可选的URL地址。

  • state object — 状态对象是一个由 pushState()方法创建的与历史纪录相关的JS对象。

  • title — 火狐浏览器现在已经忽略此参数,将来也许可能被使用。考虑到将来有可能的改变,传递一个空字符串是安全的做法。当然,你可以传递一个短标题给你要转变成的状态。

  • URL — 这个参数提供了新历史纪录的地址。请注意,浏览器在调用pushState()方法后不会去加载这个URL,但有可能在之后会这样做,比如用户重启浏览器之后。新的URL可以是绝对地址,也可以是相对地址。新URL必须和当前URL在同一个源下。

想看实现效果?参考这里一个无刷新分页的 DEMO ,建议看看源码实现。

作者:若愚

发表评论

电子邮件地址不会被公开。