旧ブログ(ISSEN)から移行しました

JavaScriptで戻る・進むを制御する方法(History API解説)

JavaScriptで戻る・進むを制御する方法(History API解説)

塩見直樹
塩見直樹5分で読めます

はじめに

こんにちは、株式会社TOKOSのナオキです!

プロジェクトを実装している際、ブラウザの「戻る」や「進む」の動作に悩まされたことはありませんか?
たとえばユーザーがフォーム入力中に誤って戻るボタンを押してしまい、入力内容が消えてしまうといったケースです。
そんな悩みを解決してくれるのが、今回ご紹介するHistory API です。
History APIを活用すれば、アプリケーションにおける画面遷移をより直感的に、ユーザー体験を損なうことなく実現できます。
この記事では、基本的な使い方から具体的な実装例までをわかりやすく解説していきますので、ぜひ最後まで読んでみてください!

対象読者

  • 初学者の方
  • フロントエンド開発をされている方

History APIとは

History APIとは、ブラウザが持つ「履歴」をJavaScriptから操作することのできるAPIのことです。
通常、ブラウザの「戻る」「進む」ボタンはユーザーが操作するもので、開発者が直接制御することはできません。
しかし、History APIを使うことで、アプリケーションから以下のような操作が可能になります。

  • ブラウザの「戻る」「進む」と同じ動作を実行する
  • ページをリロードせずにURLを変更し、履歴に新しい状態を追加する
  • 現在の履歴を新しい内容で置き換える
  • ユーザーが戻る / 進むを操作したときにイベントを検知して処理を実行する

History APIの基本的な使用方法

ここでは代表的な使用方法を紹介します!

履歴を移動する方法

history.back() - 1つ前に戻る

JavaScript
history.back()

ブラウザの「戻る」と同じ動作です。

history.forward() - 1つ先に進む

JavaScript
history.forward()

ブラウザの「進む」と同じ動作です。

history.go() - 指定した数だけ移動する

JavaScript
history.go(0) // 現在のページを再読み込みする
history.go(1) // 1つ先に進む
history.go(-2) // 2つ前に戻る

負の数で戻り、正の数で進みます。

履歴を追加・置き換える方法

history.pushState() - 履歴を追加

JavaScript
history.pushState({ page: 1 }, "", "/page1")

指定したURLをリロードしないで更新し、履歴をブラウザに保存できます。
第一引数には、履歴に紐づけて保存して置きたいデータを指定できます。
戻る / 進むで追加した履歴に戻った場合、window.history.stateで保存した情報を取得できます。
第二引数には、元々ページのタイトルを指定できましたが、現在では対応しているブラウザがほとんどなく無視されてしまいます。
省略することが出来ないので空文字を渡します。
以下ドキュメントからの引用:

このパラメータは歴史的な理由で存在しており、省略することはできません。空の文字列を渡すと、メソッドの将来の変更に対して安全になります。

第三引数には、URLを指定できます。同一オリジンのURLのみ指定可能です。

ナオキナオキ

同一オリジンとは、スキーム、ドメイン、ポート番号がすべて同じであることだね!

history.replaceState() - 履歴を置き換える

JavaScript
history.replaceState({ page: 2 }, "", "/page2")

現在の履歴を新しい内容で置き換えることができます。
引数にいれる値は、上記のpushState()と同じです。
pushState()が新しい履歴を追加するのに対して、replaceState()は今の履歴を上書きします。
つまり、履歴の数は増えずに中身だけ差し替わるということです。

履歴の変化を検知する方法

popstate - 履歴の変更を検知

JavaScript
window.addEventListener("popstate", (event) => {
  console.log("ユーザーにて「進む / 戻る」操作が行われました")
  console.log(event.state)
})

戻る / 進むで履歴の変更がされたときに発生するイベントです。
event.stateにてpushStatereplaceStateで保存したデータを取得できます。

フォーム入力中のブラウザバックを防止する方法

Web上のフォームを利用していると、ユーザーが誤って「戻る」ボタンを押してしまい、入力内容が消えてしまうことがあります。
これはユーザーにとって大きなストレスとなります。
この問題をHistory APIを活用して軽減する方法を紹介します。

JavaScript
// 履歴を追加して「戻る」で前のページにすぐ戻れないようにする
history.pushState(null, "", "/form")
 
// popstateイベントで検知して「はい / いいえ」のダイアログを表示
window.addEventListener("popstate", (event) => {
  const result = confirm("入力内容が失われます。本当に戻りますか?")
  if (result) {
    // はい → 実際に戻す
    history.back()
  } else {
    // いいえ → 履歴を積み直して戻らせない
    history.pushState(null, "", "/form")
  }
})

最初のpushState()でフォームページに入った時点で履歴を1つ追加します。
これにより「戻る」を押してもすぐに前のページへは移動せず、代わりにpopstateが発火します。
その際「入力内容が失われます。本当に戻りますか?」という確認ダイアログを表示します。
ダイアログの選択によって次のように分岐します。
「はい」→ history.back()により前のページへ遷移し、入力中のデータは失われます。
「いいえ」→ 再度pushState()で履歴を積み直し、ページに留まっているため入力データは保持されます。
このような仕組みにより、History APIを利用することで「フォーム入力中に誤って戻るボタンを押してしまう」問題を軽減できます。

さいごに

今回はHistory APIの基本から実際の使い方を紹介しました。
上記で紹介した以外の場面でも応用できるので、きっと役立つはずです。
まずはちょっとした場面から取り入れてみて、自分のプロジェクトに合った使い方を探してみてください。

この記事を書いた人

塩見直樹
塩見直樹

TOKOSのバックエンドエンジニア。パフォーマンス最適化と可読性の向上を目指しています。アニメ好きで、特にHUNTER×HUNTERが好きです。