JavaScript 逆引き集 | popstate イベント検知

JavaScript JavaScript
スポンサーリンク

popstate イベント検知 — window.addEventListener('popstate', ()=>{})

popstate イベントは ブラウザの「戻る」「進む」操作や history.back() / history.forward() が呼ばれたときに発火します。history.pushStatehistory.replaceState で履歴に状態オブジェクトを保存しておくと、その状態を event.state から取り出して画面を復元できます。SPA(シングルページアプリケーション)や検索条件の保持に必須の仕組みです。


基本のコード例

<button id="next">次へ</button>
<div id="content">初期ページ</div>

<script>
  const content = document.getElementById("content");
  let page = 1;

  // 「次へ」ボタンで履歴を積む
  document.getElementById("next").addEventListener("click", () => {
    page++;
    content.textContent = `Page ${page}`;
    history.pushState({ page }, "", `?page=${page}`);
  });

  // 戻る/進むで状態を復元
  window.addEventListener("popstate", (e) => {
    if (e.state?.page) {
      page = e.state.page;
      content.textContent = `Page ${page}`;
    } else {
      content.textContent = "初期ページ";
      page = 1;
    }
  });
</script>
HTML
  • ポイント:
    • pushState で履歴を積むと、戻る/進むで popstate が発火。
    • event.state に保存したオブジェクトが入っている。

よく使うテンプレート集

タブ切り替えを履歴に反映

function showTab(tab) {
  document.querySelectorAll(".tab").forEach(el => el.classList.add("hidden"));
  document.getElementById(tab).classList.remove("hidden");
  history.pushState({ tab }, "", `?tab=${tab}`);
}

window.addEventListener("popstate", (e) => {
  const tab = e.state?.tab || "home";
  showTab(tab);
});
JavaScript
  • ラベル: 戻る/進むでタブ状態を復元できる。

検索条件を履歴に保持

function applySearch(q) {
  document.getElementById("result").textContent = `検索結果: ${q}`;
  history.replaceState({ q }, "", `?q=${encodeURIComponent(q)}`);
}

window.addEventListener("popstate", (e) => {
  const q = e.state?.q || "";
  document.getElementById("result").textContent = `検索結果: ${q}`;
});
JavaScript
  • ラベル: 検索条件をURLに反映し、戻る/進むで復元。

実務でのコツ

  • push vs replace:
    • pushState → 履歴を積む(戻る/進むで辿れる)。
    • replaceState → 履歴を置き換える(戻る/進むでは辿れない)。
  • popstateは「戻る/進む」で発火: pushState 直後には発火しない。ユーザー操作や history.back() で発火。
  • stateオブジェクトを活用: 必要な画面状態(ページ番号、タブ名など)を保存しておくと復元が簡単。
  • URLと状態を同期: SPAでは「URL=状態」として扱うと、ブックマークや共有も自然に動く。

ありがちなハマりポイントと対策

  • pushState直後にpopstateが来ない:
    • 対策: 直後は自分で画面更新を行う。戻る/進む時だけ popstate が発火。
  • stateを保存し忘れて復元できない:
    • 対策: 必要な情報は必ず第1引数に入れる。
  • 外部URLを指定してエラー:
    • 対策: 同一オリジン内のパスだけ変更可能。

練習問題(ページ番号付きリスト)

<ul id="list"></ul>
<button id="next">次へ</button>

<script>
  const list = document.getElementById("list");
  let page = 1;

  function render() {
    list.innerHTML = "";
    for (let i = 1; i <= 5; i++) {
      const li = document.createElement("li");
      li.textContent = `Page ${page} - Item ${i}`;
      list.appendChild(li);
    }
  }

  document.getElementById("next").addEventListener("click", () => {
    page++;
    render();
    history.pushState({ page }, "", `?page=${page}`);
  });

  window.addEventListener("popstate", (e) => {
    page = e.state?.page || 1;
    render();
  });

  render();
</script>
HTML
  • 効果: 「次へ」で履歴が積まれ、戻る/進むでページ番号が復元されます。

直感的な指針

  • 「戻る/進むで状態復元」= popstate。
  • pushStateで履歴を積み、stateに必要情報を保存。
  • popstateで event.state を読んで画面を再構築。
  • SPAや検索条件保持に必須の仕組み。
タイトルとURLをコピーしました