Knowledge

Barba.jsでブラウザバック時のスクロール位置を調整してみる

  • 投稿日:
    2023/05/21
  • 更新日:
    2023/05/23
  • 読了時間:
    5分程度
Barba.jsでブラウザバック時のスクロール位置を調整してみるのサムネイル

ブラウザバック時のスクロール位置問題

本サイトでも利用しているBarba.js(V2)ですが、SPAなサイト構築の際になにかとネックになってくるのが画面遷移後のスクロール位置の問題、その中でもユーザビリティを左右するのがブラウザバック時のスクロール位置の問題になるかなと思います。

Barba.jsの記事自体は多数存在しているのですが、いまいちうまく動作しないものも多いようでしたので、本サイト制作時に実装したコードを紹介させていただきたいと思います。

スクロール位置記憶をマニュアルに

ブラウザのスクロール位置記憶がデフォルトでは

history.scrollRestoration = "auto"

になっており、スクロールしていた位置を記憶してくれるようになっているのですが、このままだと非同期遷移時にスクロール位置を記憶してしまって、ページの中途半端なところから表示されるようになってしまうケースがあります。

したがって、あえて位置の記憶をautoにせずmanualとしておきます。

//スクロール位置記憶(auto or manual=自動で記憶しない)
if (history.scrollRestoration) {
  history.scrollRestoration = 'manual';
}

ブラウザバック時を検知する

公式のドキュメントを見ると

Properties attached to data object:

PropertyTypeDescription
data.currentObjectCurrent page related
data.nextObjectNext page related
data.triggerHTMLElementLink that triggered the transition
String 'barba'Programmatic navigation
String 'back' | 'forward'Browser backward/forward button
参考:https://barba.js.org/docs/advanced/hooks/#data-properties

と記載されているので、data.trigger‘back’を返す時はブラウザバック時であるということがわかります。

最終コード

というわけで最終的なコード(の抜粋)は以下の通りとなります。

//スクロール位置記憶(auto or manual=自動で記憶しない)
if (history.scrollRestoration) {
  history.scrollRestoration = 'manual';
}

let scrollY = 0;
barba.init({
  transitions: [{
    after(data){
      if(data.trigger == 'back'){
        //ブラウザバック時
        window.scrollTo(0, scrollY);
      }else{
        //それ以外の遷移時はページの先頭に
        window.scrollTo(0, 0);
      }
      //barba.history.current.scroll.yで遷移前のページのスクロールY座標を取得
      scrollY = barba.history.current.scroll.y;
    }
  }]
});

なお、動作タイミングをafter(data)としているのは、こちらのつくりの問題もあるかもしれませんが、すべての読み込みが完了してからでないとスクロール位置が正しく動作しないケースがあるためとなります。
コード内ではブラウザバック時を対象としていますが、ブラウザバック後に前のページに戻る‘forward’も同様にdata.triggerで取得してスクロール位置をセットしてあげればよいかと思います。

何かの参考になれば幸いです。