使用history.state来保存scrollTop?

时间:2013-01-26 20:44:11

标签: javascript browser-history

我过度设计的网络应用程序:

  • 使用history.pushStatepopState个事件来动画显示网址之间的动作,而无需在网址中使用#
  • 使用外部div来处理滚动条,html和正文具有overflow:hidden。当用户点击它时,它就是这样,在动画左侧之前它不会跳到顶部。

现在我的问题是,如果用户再次点击前进按钮,我怎样才能保留它们滚动的位置/将它们滚动回原位。

  • 我的第一个想法是使用history.state对象作为保存滚动位置的位置,然后在用户向前点击时加载它。 (我必须在没有replaceState对象的第一页上history.state。)这个想法的问题是,一旦用户点击回来,我就无法再将scrollTop添加到当前状态。

  • 我的下一个想法是使用一个单独的数组,所以我通过索引拉出滚动位置,但问题是如果用户关闭选项卡然后重新打开它,或者他们导航到了另一个网站,然后回到我的网站,他们的前后历史被保存了,但我的单独scrollTop数组将丢失。

你的建议是什么?

3 个答案:

答案 0 :(得分:1)

Jörn Zaefferer已针对此问题编写了一种方法:https://github.com/jzaefferer/pitfalls-examples/blob/master/app/gallery/gallery.js#L29-37

(如果您的母语是德语,请查看他的演讲:http://www.youtube.com/watch?v=RGdbfKgPKI8

答案 1 :(得分:1)

如前所述,可以使用历史API的状态对象来跟踪页面的当前状态(例如滚动位置或表单字段条目)。

当然,在某些时候,必须将页面状态存储到历史状态对象中。但是,当浏览器触发了一个popstate事件时,它已经太晚了,因为之前的历史状态已经被弹出的状态所取代。

因此必须在popstate事件之前存储页面状态。但是,由于没有beforepopstate事件,唯一可行的方法是不断监听页面状态的变化(例如滚动或输入事件),并使用replaceState不断更新当前的历史状态对象。

但是,在基于Chromium的浏览器中,每次调用replaceState都会向用户简要显示加载指示符。如果你不想这样,只需在popstate事件后调用replaceState。在此调用中,将唯一ID存储在历史状态对象中。使用此唯一ID作为密钥,以在浏览器的会话存储中存储更多状态。 (您必须为缓存建模,因为条目可能会成为状态。)

答案 2 :(得分:0)

使用pushState,您可以将数据添加到历史记录状态,如下所示:

var stateObj = { scrollTop: "500px" };
history.pushState(stateObj, "page 2", "page.html");

当触发window.onpopstate事件时,它将返回stateObj(event.state),并且有你的scrollTop位置。

有一个很好的插件来控制Windows历史记录:

jQuery动态网址:https://github.com/promatik/jQuery-Dynamic-URL

请看这个例子:http://promatik.no.sapo.pt/github/dynamic-url/