この翻訳は不完全です。英語から この記事を翻訳 してください。
DOM window
オブジェクトは history
オブジェクトを介したブラウザの履歴へのアクセスを提供しています。このオブジェクトでは、前のページに戻ったり、( HTML5 からは履歴スタックの中身を操作できるなど)ユーザーの履歴を行き来するのに便利なメソッドとプロパティが提供されています。
履歴情報を用いて移動する
back()
, forward()
, go()
メソッドを使用することにより、ユーザーの履歴を通して、前のページに戻ったり、次のページへと移動します。
前のページや次のページへ移動する
履歴情報を通して前のページに戻るためには、このようにします:
window.history.back();
これにより、ちょうどユーザーがブラウザのツールバーの「前のページに戻る」ボタンをクリックしたときのような挙動がなされます。
同様に、このようにすることで(ユーザーが「次のページへ進む」ボタンをクリックしたかのように)次のページへ進むこともできます:
window.history.forward();
履歴の指定した位置まで移動する
go()
メソッドを使い、セッション履歴において現在のページと相対的な位置にある特定のページを読み込むことができます。(もちろん、現在のページのインデックスは 0 となります)
ひとつ前のページへと戻ります。( back()
と同様の動き):
window.history.go(-1);
forward()
を呼び出したのと同様に、次のページへと移動します:
window.history.go(1);
同じように、2 を渡せば、2ページ進むことも戻ることもできます。
length
プロパティの値を参照することにより、履歴スタック中のページの数を知ることができます:
var numberOfEntries = window.history.length;
go()
のパラメータとして URL 文字列を渡すことができます。ですが、これは非標準の機能であり Gecko ではサポートされていません。履歴エントリの追加と修正
HTML5 では history.pushState()
および history.replaceState()
メソッドが導入され、それぞれにより履歴エントリの追加と修正が可能となりました。 これらのメソッドは window.onpopstate
イベントと連動して動作します。
history.pushState()
を使うことで、履歴の状態を変更した後に生成される XMLHttpRequest
オブジェクトの HTTP ヘッダー中のリファラも変更されます。リファラは XMLHttpRequest
オブジェクトが生成された時点での this
となるウィンドウの持つドキュメントの URL となります。
例
下記の JavaScript は https://mozilla.org/foo.html において実行されていると仮定します:
var stateObj = { foo: "bar" }; history.pushState(stateObj, "page 2", "bar.html");
これにより URL バーには https://mozilla.org/bar.html と表示されますが、bar.html
が存在しているかどうかに関わらずブラウザが bar.html
をロードすることはありません。
戻るボタンを押したことにより、ユーザーは現在、 https://google.com に移動しようとしていると仮定しましょう。この時点では、URL バーは https://mozilla.org/bar.html を表示しており、ページは、stateObj
のコピーを含む state オブジェクトを持つ popstate
イベントを取得します。popstate
イベントの間に、ページのコンテンツは修正されるにも関わらず、ページ自体は foo.html
であるように見えるでしょう。
再度「戻る」ボタンを押すことにより、URL は https://mozilla.org/foo.html へと変わり、ドキュメントは別の popstate
イベントを取得します。このとき state オブジェクトは null となっています。ここでも、popstate
イベントを受け取った際にドキュメントによってコンテンツが手動で修正されたにもかかわらず、「戻る」挙動によって、前ステップのものからドキュメントのコンテンツが変更されることはありません。
pushState() メソッド
pushState()
は、state オブジェクト、タイトル(現在のところ無視されます)、そしてURL(任意)の3つのパラメータを使用します。これら3つのパラメータについて詳細に見ていきましょう:
-
state オブジェクト — state オブジェクトは
pushState()
によって作成される新しい履歴エントリに関連付けられる JavaScript オブジェクトです。ユーザーが新しいエントリに移動すればいつでも、popstate
イベントが発火して、履歴エントリの state オブジェクトのコピーがイベントのstate
プロパティへと含まれることとなります。state オブジェクトは何であってもシリアライズされます。Firefox はユーザーのディスクに state オブジェクトを保存し、ユーザーがブラウザを再起動した際に state オブジェクトを復元するため、シリアライズされた状態での state オブジェクトの最大文字数は640000文字と、サイズの制限がされています。シリアライズ後にこの最大文字数を上回ることになる state オブジェクトを
pushState()
に渡した場合、pushState()
は例外を投げます。これを上回るスペースが必要な場合、sessionStorage
またはlocalStorage
の使用を推奨します。 -
タイトル — 将来的には使用されるようになるかもしれませんが、現在の Firefox はこのパラメータを無視します。将来的な変更に備えて、空の文字列を渡しておくべきでしょう。あるいは、移動しようとしている先の状態を示す短いタイトルを渡しておくこともできます。
-
URL — このパラメーターは、新しい履歴エントリの URL が指定します。
pushState()
の呼び出しの後、ブラウザはこの URL のロードを行わないと注記しておきますが、ユーザーがブラウザを再起動させた後などでは、新しく指定された URL をロードすることがあります。新しい URL は絶対パスである必要は無く、相対パスであった場合は、現在のURLとの相対関係が解決されます。新しい URL は現在の URLと same origin でなければなりません。でなければpushState()
は例外を発生させるでしょう。このパラメータは任意であり、指定されなかった場合は現在のドキュメントの URL が設定されます。
ある意味では、pushState()
の呼び出しは window.location = "#foo";
と設定するのと似ています。どちらも、現在のドキュメントに関連する別の履歴エントリの生成とアクティベートを行います。ですが pushState()
にはいくらかの利点があります:
- 新しい URL は、現在の URL と同じドメインであればどの URL にもなることができます。対照的に、
window.location
では hash の変更しかできず、同じdocument
のままとなります。 - 必ずしも URL を変更する必要はありません。対照的に、
window.location = "#foo";
では、現在の hash が#foo
でない場合、新しい履歴エントリの作成以外のことはできません。 - 新しい履歴エントリに任意のデータを関連付けることができます。hash を基にしたアプローチでは、関連するデータを含めた短い文字列を全てエンコードする必要があります。
新しい URLが、変更前のURLから hash のみを変更した URL である場合であっても、 pushState()
は hashchange
イベントを発火させることはないと注記しておきます。
replaceState() メソッド
history.replaceState()
は丁度 history.pushState()
のように動作しますが、pushState()
と異なる点として、 replaceState()
は新しく履歴エントリを作成する代わりに現在の履歴エントリを修正します。
具体的には、何らかのユーザーのアクションを受け、現在の履歴エントリの URL または state オブジェクトを更新したい場合に replaceState()
が役立ちます。
popstate イベント
アクティブな履歴エントリが変更される度にウィンドウへと popstate
イベントが発行されます。pushState
の呼び出しまたは replaceState
の呼び出しの影響によって、アクティベートされた履歴エントリが作成された場合、popstate
イベントの state
プロパティは履歴エントリの state オブジェクトのコピーを含みます。
使い方のサンプルは window.onpopstate
を参照してください。
現在の状態を読み取る
ページが読み込まれたとき、 ページは null ではない state オブジェクトを持っているかもしれません。これは例えば、(pushState()
または replaceState()
の使用によって)ページに state オブジェクトが設定されており、ユーザーがブラウザを再起動した場合に起こりえます。ページを再読み込みした際にページは onload
イベントを受け取りますが popstate
イベントは受け取られません。しかしながら history.state
プロパティを読み取った場合、popstate
が発火した際に取得できるであろう state オブジェクトを得ることができるでしょう。
このように history.state
プロパティを用いることで、 popstate
イベントを待つことなく現在の履歴エントリの state を読み取ることができます:
var currentState = history.state;
Examples
For a complete example of AJAX web site, Ajax navigation example をご覧ください
ブラウザ互換性
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
replaceState, pushState | 5 | 4.0 (2.0) | 10 | 11.50 | 5.0 |
history.state | 18 | 4.0 (2.0) | 10 | 11.50 | 6.0 |
機能 | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
replaceState, pushState | ? | ? | ? | ? | ? |
history.state | ? | ? | ? | ? | ? |
クロスブラウザでの互換性の問題を解消するには History.js を使うとよいかもしれません。