JavaScript 在 Hotwire Turbo 链接跳转时保持窗口滚动位置

Rei · 2022年03月01日 · 最后由 zhangkaizhao 回复于 2022年03月03日 · 473 次阅读

原文链接:https://geeknote.net/Rei/posts/393


GeekNote 使用了 Hotwire 的 Turbo,有些地方需要用到 Tab 导航。我希望在切换 Tab 的时候保持页面滚动的位置,避免页面跳动。

经过搜索,发现 Hotwire 有个 Issus 提出了这个需求,然后维护者给了官方的实现思路:https://github.com/hotwired/turbo/issues/37#issuecomment-751523976 。这个实现对当前版本有些问题,根据后面的回复我找到了适合当前版本的实现。

只需加入一段 js:

let scrollTop = 0

window.addEventListener("turbo:click", ({ target }) => {
  if (target.hasAttribute("data-turbo-preserve-scroll")) {
    scrollTop = document.scrollingElement.scrollTop
  }
})

window.addEventListener("turbo:render", () => {
  if (scrollTop) {
    document.scrollingElement.scrollTo(0, scrollTop)
    Turbo.navigator.currentVisit.scrolled = true
  }

  scrollTop = 0
})

然后在需要保持位置的链接上加上 data-turbo-preserve-scroll 属性,例如:

<div class="tab">
  <a href="..." class="tab__item" data-turbo-preserve-scroll>item</a>
</div>

这样在通过这个链接跳转页面后,页面会保持当前的滚动位置。

Ruby China 有个影响体验的问题,就是从主题列表页面进入主题页面,在这个主题页面滚动到下方某个位置,最后点击返回主题列表页面(返回操作历史的上一个),结果返回的主题列表页面并没有停留在原来的位置,而是滚动到刚刚的那个主题页面(操作历史的下一个)的滚动位置。不知道这个问题与此是否相关,但是很明显不符合预期。这个问题出现稍微有些日子了,似乎是在使用 Hotwire Turbo 之后出现的。

--更新--

哦不对,是直接滚动到最下方了……

(Firefox on macOS)

--再更新--😓

诡异的是有时候正常有时候不正常。不过,似乎是在超过一页内容的主题页面上,而且在此页面上向下滚动超过一页的内容才会发生。

这个跟 Turbolinks 时候处理思路接近😀

zhangkaizhao 回复

好像是有滚动位置不正确的行为,但是不能稳定复现。

顶楼内容没有用在 Ruby China。


作为记录:

  • 从首页进入一个页面高度比较小的主题会导致滚动位置不正确,正常应该是在顶部。

感觉 Hotwire Turbo 这套东西在 Firefox 上似乎有很多问题。

比如刚刚又发现另一个问题,对通知列表里面的每条回复的点击在 Firefox 里跳转到其主题页面后不会跳转到该回复的位置,然而在 Google Chrome 里却是可以的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号