如何使用Turbolinks刷新页面

16

我知道在Turbolinks 5上可以调用以下代码,但它会改变滚动位置。有没有一种方法可以调用Turbolinks来刷新页面而不改变滚动位置?

Turbolinks.visit(location.toString());

这可以达到我想要的效果,但我希望使用Turbolinks

 window.location.reload()
3个回答

18

在调用visit之前,存储当前滚动位置,然后在页面加载时滚动到该位置。将存储的滚动位置重置为null可确保后续页面加载不会滚动到旧位置。一种可能的实现方式如下:

var reloadWithTurbolinks = (function () {
  var scrollPosition

  function reload () {
    scrollPosition = [window.scrollX, window.scrollY]
    Turbolinks.visit(window.location.toString(), { action: 'replace' })
  }

  document.addEventListener('turbolinks:load', function () {
    if (scrollPosition) {
      window.scrollTo.apply(window, scrollPosition)
      scrollPosition = null
    }
  })

  return reload
})()

然后你可以调用reloadWithTurbolinks()

为了防止页面在滚动到所需位置时闪烁,请在页面的head中添加no-preview缓存指令:

<meta name="turbolinks-cache-control" content="no-preview">

此解决方案在 Hotwire Turbo 中无法正常工作,因为 "turbo:load" 处理程序 (https://github.com/hotwired/turbo/blob/4e3d05d7a0b61c1da3b65cd866073033ead1ee71/src/core/drive/visit.ts#L396) 在执行滚动操作之前被调用 (https://github.com/hotwired/turbo/blob/4e3d05d7a0b61c1da3b65cd866073033ead1ee71/src/core/drive/visit.ts#L398)。我的 hack-fix 是将处理程序包装到 setTimeout() 中,这样处理程序实际上会稍后执行,就像 Turbolinks 一样。代码:if (scrollPosition) { setTimeout(() => { window.scrollTo.apply(window, scrollPosition); scrollPosition = null }); }}) - xhafan

8

已经有一段时间了,不确定您是否仍需要解决方案。您可以尝试这个方法,在加载页面内容之前和之后禁用/启用滚动:

Turbolinks.enableTransitionCache(true);
Turbolinks.visit(location.toString());
Turbolinks.enableTransitionCache(false);

6
我的答案基于Dom Christie's answer,在重新加载并在渲染之前获取滚动位置后恢复焦点。
在渲染新页面之前存储当前滚动位置和活动字段项,然后在渲染完成后滚动到该存储位置并恢复焦点。重置存储的滚动位置和焦点ID为null确保后续页面加载不会滚动到旧的位置/焦点。
请注意,字段必须具有分配的ID才能恢复焦点。
var reloadWithTurbolinks = (function () {
        var scrollPosition;
        var focusId;

        function reload() {
            Turbolinks.visit(window.location.toString(), {action: 'replace'})
        }

        document.addEventListener('turbolinks:before-render', function () {
            scrollPosition = [window.scrollX, window.scrollY];
            focusId = document.activeElement.id;
        });
        document.addEventListener('turbolinks:load', function () {
            if (scrollPosition) {
                window.scrollTo.apply(window, scrollPosition);
                scrollPosition = null
            }
            if (focusId) {
                document.getElementById(focusId).focus();
                focusId = null;
            }
        });
        return reload;
    })();

然后你可以这样调用它:
 setInterval(function () {
        reloadWithTurbolinks();
 }, 3000);

我将其与表单上的"data-turbolinks-permanent"属性结合使用。我还使用<meta name="turbolinks-cache-control" content="no-preview">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接