popstateイベント
ブラウザーの戻る・進む操作に対応します
「popstateイベント」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。
popstate の働き
ユーザーが履歴をたどってナビゲーションすると(戻る、進む、または JavaScript の history.back 呼び出し)、window で popstate イベントが発生します。これにより、ブラウザーによるナビゲーションに応じて SPA が正しいビューを再描画できます。
発生するタイミング
popstate は、戻るボタンや進むボタンのクリック、history.back()、history.forward()、history.go(n) で発生します。pushState や replaceState を手動で呼び出しても発生しません。これらはプログラムによる更新であり、ページはすでにその更新を把握しているためです。
window.addEventListener("popstate", (e) => {
console.log("Navigated to", location.pathname, "state:", e.state);
renderPage(location.pathname);
});state プロパティ
イベントの state プロパティには、移動先のエントリに対して pushState や replaceState に渡した state オブジェクトが格納されます。URL に含まれない UI の状態(開いているタブやスクロール位置など)の復元に使用します。
新しい URL の読み取り
popstate が発生した時点で、アドレスバーはすでに更新されています。新しい URL を確認するには location.pathname、location.search、location.hash を読み取ります。これらを state と組み合わせれば、遷移先のビューを描画するために必要な情報がすべて得られます。
初期ページの読み込み
popstate は初期ページの読み込み時には発生せず、ナビゲーション時にだけ発生します。起動時には location から初期ビューを描画し、その後のナビゲーションを popstate に処理させてください。これを行わないと、最初の戻る操作で到達した初期ページが空白になります。
// Initial render
renderPage(location.pathname);
// Future navigation
window.addEventListener("popstate", () => renderPage(location.pathname));hashchange と popstate
純粋なハッシュベースのルーティング(/#/about のような URL)では、ハッシュが変わると hashchange イベントが発生します。popstate はパスの変更でも発生します。現在の SPA では History API と popstate が使われ、ハッシュルーティングはレガシーな方式です。
クリックの横取り
通常の <a> のクリックでクライアント側のナビゲーションを実行するには、クリックを横取りして preventDefault を呼び出し、pushState と renderPage を実行します。修飾キー(新しいタブで開く Cmd/Ctrl クリックなど)も確認し、その場合はデフォルトの動作に任せてください。
document.addEventListener("click", (e) => {
const a = e.target.closest("a");
if (!a || a.target || e.metaKey || e.ctrlKey) return;
e.preventDefault();
history.pushState(null, "", a.href);
renderPage(location.pathname);
});スクロール位置の復元
ブラウザーは戻る操作の際にスクロール位置を自動復元しようとしますが、SPA ではコンテンツが非同期に描画されるため、この動作は信頼できません。スクロール位置を pushState の state に保存し、popstate で復元してください。window.scrollTo(0, e.state?.scroll ?? 0) のように記述できます。
非同期描画に関する注意点
renderPage が非同期でデータを取得する場合、コンテンツが届く前に URL が更新されます。読み込み中の状態を表示してから描画してください。取得中にユーザーが戻る操作を行ったとき、キャンセルされた取得結果が新しいビューを上書きする競合状態を避ける必要があります。
フレームワークのルーター
React Router、Vue Router、SvelteKit のルーターはいずれも History と popstate をラップしています。フレームワークを使わない場合でも、基盤となる仕組みは同じです。popstate を監視し、リンクを横取りして pushState を呼び出します。オーバーヘッドが問題になる場合は、バニラ JavaScript で約 50 行のルーターを自作できます。
よくある落とし穴: メモリリーク
各ビューのセットアップでは、イベントリスナーやタイマーを登録することがあります。ビューが変わるとき(popstate 内や pushState のラッパー内)に明示的な破棄処理を行わないと、リスナーが蓄積して時間とともにパフォーマンスが低下します。ビューごとの購読を AbortController で管理し、ビューが変わるときに中断してください。
理解度チェック
自分で history.pushState を呼び出したとき、popstate イベントが発生しないのはなぜですか。
まとめ
popstate はブラウザーの戻る・進む操作で発生し、保存された state と新しい location にアクセスできます。pushState や replaceState の呼び出し時には発生しません(コードがすでに把握しているためです)。また、初期ページの読み込み時にも発生しないため、手動で描画する必要があります。SPA のナビゲーションではリンクのクリックを横取りし、state にスクロール位置を保存し、ビューの変更時にリスナーを破棄してリークを防いでください。
よくある質問
「popstateイベント」レッスンは無料ですか?
はい。「popstateイベント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。
「popstateイベント」で何を学びますか?
ブラウザーの戻る・進む操作に対応します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
HTML Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「popstateイベント」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このHTML Academyレッスンでコードを書いて実行できますか?
はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。