web-dev-qa-db-ja.com

Turbolinksでページを更新する方法

Turbolinks 5 で次のコードを呼び出すことができることを理解していますが、スクロール位置が変更されます。 Turbolinksを呼び出してページを更新し、スクロール位置を変更しない方法はありますか?

Turbolinks.visit(location.toString());

これは私が望むことをしますが、Turbolinksを使用することを望んでいました

 window.location.reload()
13
John Pollard

visitを呼び出す前に現在のスクロール位置を保存し、ページが読み込まれたら、その保存された位置までスクロールします。保存されているスクロール位置をnullにリセットすると、後続のページの読み込みで古い位置にスクロールされなくなります。考えられる実装の1つは次のとおりです。

_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">
_
6
Dom Christie

それでも解決策が必要かどうかはわかりませんが、しばらくの間はメリットがあります。これを試すことができます。これにより、ページコンテンツの読み込みの前後にスクロールが無効/有効になります。

Turbolinks.enableTransitionCache(true);
Turbolinks.visit(location.toString());
Turbolinks.enableTransitionCache(false);
5
Hung Tran

私の答えは Dom Christieの答え に基づいており、リロード後にフォーカスが復元され、レンダリングの直前にscrollPositionが取得されます。

新しいページをレンダリングする前に現在のスクロール位置とアクティブなフィールドアイテムを保存し、がレンダリングされた後、その保存された位置までスクロールしてフォーカスを復元します。保存されたスクロール位置とfocusIdを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">も使用しています。

3
Synox