JavaScript | Web API:ウィンドウ・ブラウザ制御 - history API

JavaScript JavaScript
スポンサーリンク

history API は「ブラウザの戻る・進むをコードから操る仕組み」

historywindow.history のことで、
ブラウザの「戻る」「進む」ボタンと同じようなことを、JavaScript から行うための API です。

今までに辿ってきたページの履歴
履歴の数
一つ前に戻る
一つ先に進む
URL だけ書き換えて「遷移した風」に見せる(SPA で超重要)

こういったことを扱えます。

特に、pushState / replaceState を使うと、
「ページをリロードせずに URL だけ変える」ことができるので、
シングルページアプリ(SPA)では必須級の API になっています。


一番基本:back / forward / go で履歴を動かす

戻る・進むをコードから呼ぶ

ブラウザの戻るボタンと同じことをするのが history.back() です。

history.back();    // 1つ前のページへ戻る
history.forward(); // 1つ先のページへ進む
JavaScript

back() は「戻るボタン」、forward() は「進むボタン」と覚えてOKです。

「n 個分まとめて動かしたい」ときは history.go() を使います。

history.go(-1); // 1つ戻る(back() と同じ)
history.go(1);  // 1つ進む(forward() と同じ)
history.go(-2); // 2つ前に戻る
JavaScript

マイナスで戻る、プラスで進む、というイメージです。

履歴の長さを知る:history.length

history.length で、
「このタブで辿ってきた履歴の数」が分かります。

console.log(history.length); // 例: 5
JavaScript

ただし、「何個前まで戻れるか」が正確に分かるわけではありません。
あくまで「このセッションで何ステップ分の履歴があるか」の目安です。


重要ポイント:pushState / replaceState で「リロードせずに URL を変える」

ここが history API の一番おいしいところです。
少し丁寧にやります。

pushState の基本形

pushState は、
「履歴に新しいエントリを追加しつつ、URL を書き換える」メソッドです。

history.pushState(state, title, url);
JavaScript

それぞれの意味はこうです。

state
好きなオブジェクトを入れられる(後で取り出せる「メモ」)

title
今はほぼ無視されることが多い(空文字でよい)

url
新しく表示したい URL(同一オリジン内に限る)

例えば、タブをリロードせずに /about に「遷移した風」にしたいならこうです。

history.pushState({ page: "about" }, "", "/about");
JavaScript

これで、アドレスバーの表示は /about に変わりますが、
ページ全体のリロードは起きません。
「SPA のルーティング」がまさにこれです。

replaceState は「履歴を上書き」

replaceStatepushState に似ていますが、
「新しい履歴を追加する」のではなく、
「今の履歴を上書きする」という違いがあります。

history.replaceState({ page: "home" }, "", "/home");
JavaScript

戻るボタンで戻ってきてほしくないような場面
(例: ログイン直後のリダイレクト)
では replaceState が使われます。

state は「その履歴に紐づく自由なメモ」

pushState / replaceState の第1引数 state は、
その履歴エントリに紐づく「好きなデータ」を入れておける場所です。

例えば、

history.pushState({ tab: "profile" }, "", "/user/10?tab=profile");
JavaScript

とすると、
「この URL に来たときは tab=profile だった」という情報を
state に持たせておけます。

後でこの履歴に戻ってきたとき、
popstate イベントでこの state を受け取れます。


popstate イベントで「戻る・進む」を検知する

戻る・進むが押されたときに呼ばれるイベント

pushState / replaceState を使っていると、
ユーザーが「戻る」「進む」を押したときに、
自分で UI を切り替えたい場面が出てきます。

そのときに使うのが popstate イベントです。

window.addEventListener("popstate", (event) => {
  console.log("popstate!", event.state);
});
JavaScript

event.state には、
pushState / replaceState で渡した state オブジェクトが入っています。

これを使って、
「どの画面を表示すべきか」を決めるのが SPA の基本パターンです。

簡単な SPA 風ルーティングの例

HTML をざっくり想像します。

<nav>
  <a href="/" data-page="home">Home</a>
  <a href="/about" data-page="about">About</a>
</nav>
<div id="view"></div>

JavaScript はこんな感じ。

const view = document.querySelector("#view");

function render(page) {
  if (page === "home") {
    view.textContent = "これはホームです";
  } else if (page === "about") {
    view.textContent = "これはアバウトです";
  }
}

function navigate(page, url) {
  history.pushState({ page }, "", url);
  render(page);
}

// 初期表示
render("home");

// ナビゲーションのクリックを横取り
document.querySelector("nav").addEventListener("click", (e) => {
  if (e.target.matches("a[data-page]")) {
    e.preventDefault();
    const page = e.target.dataset.page;
    const url = e.target.getAttribute("href");
    navigate(page, url);
  }
});

// 戻る・進むに対応
window.addEventListener("popstate", (event) => {
  const state = event.state;
  if (state && state.page) {
    render(state.page);
  } else {
    render("home");
  }
});
JavaScript

ここでやっていることは、

リンククリック時にページ遷移を止める
代わりに pushState で URL を変える
自分で render を呼んで画面を書き換える
戻る・進むが押されたら popstate で state.page を見て render

という流れです。

これが「SPA のルーティングの超ざっくり版」です。
history API の本領がここにあります。


history API を使うときの注意点

別ドメインには勝手に飛べない(同一オリジン制限)

pushState / replaceStateurl は、
「同じオリジン(スキーム・ホスト・ポートが同じ)」である必要があります。

例えば、今 https://example.com にいるときに、

history.pushState({}, "", "https://google.com");
JavaScript

のようなことはできません。

別ドメインに行きたいときは、
素直に location.href = "https://google.com" などで遷移します。

state に入れるデータは「シリアライズ可能なもの」にする

state にはオブジェクトを入れられますが、
あまり巨大なデータや関数などは入れないほうがよいです。

基本的には、

JSON にできるような素直なオブジェクト
(数値、文字列、配列、ネストしたオブジェクトなど)

にしておくと安全です。


初心者として history API で本当に掴んでほしいこと

history は「ブラウザの戻る・進むをコードから扱うための API」
back / forward / go で履歴を移動できる
pushState / replaceState で「リロードせずに URL を変えられる」
state に「その履歴に紐づくメモ」を入れておける
popstate イベントで「戻る・進むが押されたとき」に UI を切り替えられる

まずはブラウザのコンソールで、

console.log(history.length);
history.pushState({ n: 1 }, "", "/test1");
history.pushState({ n: 2 }, "", "/test2");
console.log(history.length);
JavaScript

などを試してみてください。

そのうえで、
「戻るボタンを押したときに画面の内容を変える小さなデモ」
を自分で書いてみると、
history API が「ただのおまけ」ではなく、
「時間と画面遷移をコントロールするための強力な道具」 だと実感できるはずです。

タイトルとURLをコピーしました