履歴 API の操作
pushState()
および replaceState()
メソッドは、それぞれ履歴項目を追加したり変更したりします。これらのメソッドは popstate
イベントと一緒に動作します。
履歴項目の追加と修正
pushState()
を使うことで、履歴の状態を変更した後に生成される XMLHttpRequest
オブジェクトの HTTP ヘッダー中のリファラも変更されます。リファラーは XMLHttpRequest
オブジェクトが生成された時点での this
となるウィンドウの持つ文書の URL となります。
pushState() の例
以下の JavaScript が https://mozilla.org/foo.html
で実行されると想定してください。
const stateObj = {
foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");
これにより URL バーには https://mozilla.org/bar.html
と表示されますが、ブラウザーは bar.html
を読み込むことはなくまたその存在をチェックすることはありません。
ユーザーが https://google.com
へ移動し、それから戻るボタンをクリックしたとします。このとき、 URL バーは https://mozilla.org/bar.html
を表示し、history.state
は stateObj
になります。popstate
イベントはページが再読み込みされたために発行されません。ページそれ自体は bar.html
のように見えます。
再び戻るボタンをクリックすると、URL は https://mozilla.org/foo.html
へ変化し、 popstate
イベントが発行され、状態は null オブジェクトとなります。ここでもまた、popstate
イベントを受け取って手動でコンテンツを変更することは可能ですが、戻るという操作によって戻る前のコンテンツが変更されるわけではありません。
pushState() メソッド
pushState()
は、 状態オブジェクト、title (今は無視されます)、(任意で) URL の 3 つの引数を使用します。
これら 3 つの引数について詳細に見ていきましょう。
- 状態オブジェクト
-
状態オブジェクトは JavaScript のオブジェクトで、
pushState()
によって作成された新しい履歴項目と関連付けられています。ユーザーが新しい状態に遷移するたびにpopstate
イベントが発行され、そのイベントのstate
プロパティに履歴項目の状態オブジェクトのコピーが格納されます。 状態オブジェクトはシリアライズ可能なものであれば何でも構いません。Firefox は状態オブジェクトをユーザーのディスクに保存し、ユーザーがブラウザーを再起動した後に復元できるようにするため、状態オブジェクトのシリアライズ表現に 640k 文字というサイズ制限を課しています。もし、シリアライズされた表現がこれより大きい状態オブジェクトをpushState()
に渡すと、このメソッドは例外を発生します。これ以上の領域が必要な場合は、sessionStorage
やlocalStorage
を使用することをおすすめします。 - title
-
Safari 以外のすべてのブラウザーは、現在この引数を無視しています。ただし、将来的には使用する可能性があります。ここで空文字列を渡せば、将来このメソッドが変更されても安全です。あるいは、移動先の状態を表す短いタイトルを渡すこともできます。
- URL
-
新しい履歴項目の URL はこの引数で与えられます。ブラウザーは
pushState()
の呼び出しの後にはこの URL を読み込もうとしませんが、例えばユーザーがブラウザーを再起動した後などには URL を読み込もうとする可能性があることに注意してください。新しい URL は絶対的である必要はありません。相対的である場合、現在の URL に対して相対的に解決されます。新しい URL は現在の URL と同じオリジンでなければなりません。そうでない場合、pushState()
は例外を発生します。この引数はオプションです。指定しなかった場合、文書の現在の URL が設定されます。
ある意味では、pushState()
の呼び出しは window.location = "#foo"
と設定するのと似ています。どちらも、現在の文書に関連する別の履歴項目の生成と有効化を行います。
しかし、 pushState()
にはいくらかの利点があります。
- 新しい URL は、現在の URL と同じオリジンであればどの URL にもなることができます。対照的に、
window.location
では同じdocument
のままで、ハッシュの変更のみが可能です。 - 必ずしも URL を変更する必要はありません。逆に、
window.location = "#foo";
では、現在のハッシュが#foo
でない場合、新しい履歴項目の作成以外のことはできません。 - 新しい履歴項目に任意のデータを関連付けることができます。ハッシュを基にしたアプローチでは、関連するデータを含めた短い文字列を全てエンコードする必要があります。
- その後、
title
がブラウザーで使用された場合、このデータを(例えばハッシュとは関係なく)使用することができます。
新しい URL が古い URL とハッシュだけ異なっていても、 pushState()
は決して hashchange
イベントを発行させないことに注意してください。
他の文書では、 null
の名前空間 URI を持つ要素を作成します。
replaceState() メソッド
history.replaceState()
はちょうど history.pushState()
のように動作しますが、 replaceState()
は新しく履歴項目を作成するのではなく、現在の履歴項目を修正します。ただし、グローバルなブラウザー履歴に新しい項目が作成されるのを防ぐものではありません。
具体的には、何らかのユーザーのアクションを受け、現在の履歴項目の URL または 状態オブジェクトを更新したい場合に replaceState()
が役立ちます。
replaceState() の例
https://mozilla.org/foo.html
で次の JavaScript を実行したとします。
const stateObj = {
foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");
上記2行の説明は、上記の pushState() メソッドの例 の部分で得ることができます。
次に、https://mozilla.org/bar.html
で次の JavaScript を実行したとします。
history.replaceState(stateObj, "page 3", "bar2.html");
これによって URL バーには https://mozilla.org/bar2.html
が表示されますが、ブラウザーは bar2.html
の読み込みを行わず、bar2.html
が存在するかどうかもチェックしません。
仮に今、ユーザーが https://www.microsoft.com
へ移動し、戻るボタンを押したとします。この時点で URL バーには https://mozilla.org/bar2.html
が表示されています。もしユーザーが再び戻るボタンを押すと、 URL バーには https://mozilla.org/foo.html
が表示され、bar.html
を完全に回避します。
popstate イベント
アクティブな履歴項目が変更される度にウィンドウへと popstate
イベントが発行されます。pushState
の呼び出しまたは replaceState
の呼び出しの影響によって、アクティベートされた履歴項目が作成された場合、popstate
イベントの state
プロパティは履歴項目の 状態オブジェクトのコピーを含みます。
使い方の例は popstate
を参照してください。
現在の状態を読み取る
ページが読み込まれたとき、 ページには null ではない状態オブジェクトがあるかもしれません。これが起こるのは、例えば、(pushState()
または replaceState()
) の使用によって)ページに状態オブジェクトが設定されており、ユーザーがブラウザーを再起動した場合です。ページを再読み込みした際にページは onload
イベントを受け取りますが popstate
イベントは受け取られません。しかしながら history.state
プロパティを読み取った場合、popstate
が発行された際に取得できるであろう状態オブジェクトを得ることができるでしょう。
このように history.state
プロパティを用いることで、 popstate
イベントを待つことなく現在の履歴項目の状態を読み取ることができます。
const currentState = history.state;
関連情報
- 履歴 API
- 履歴ナビゲーションの例
history
グローバルオブジェクト