“History” – Alphabetical Advent Calendar 2013
この記事は賞味期限切れです。(更新から1年が経過しています)
“H” は History の “H”。
History による履歴操作
一画面で構成される様なWebアプリケーションで ユーザーに「戻る」ボタンなどの履歴移動機能を提供したい場合、 旧来は location.hash を使用していました。
window.addEventListener("hashchange", function(){
/* location.hash が変更された時の処理 */
}, false);
location.hash = "foo"; // "#foo" に移動
URL末尾のハッシュは更新されますが 表示されているドキュメント自体は切り替わらず、 そのハッシュの名前によってページの一部を切り替えたり、 少し変わったトランジションをかけてページを移動したりする事が出来ます。 URLの文字は変更されているので、その状態をブックマークする事も出来ます。
最近ではその役割に、Historyオブジェクトに新たに実装された pushState が取って代わりつつあります。
History.pushState を使う
まず、History オブジェクト自体は一度は使った事がある代物だと思いますが、 window にぶらさがっているあの history の事です。 配列のように履歴の情報をスタックしていけるようなオブジェクトで、 go/back/forward() メソッドを使うことでその履歴間を行き来する事が出来ます。
pushState() は、Historyオブジェクトに新しく履歴のエントリを追加し、そこに移動するメソッドです。 例えば http://example.com のページで次のような処理をした場合。
var url = "/foo";
history.pushState({url: url}, "", url);
アドレスバーのURLは http://example.com/foo に切り替わりますが、ページの表示はそのままです。 pushState をコールした後に自分で好きなようにドキュメントを弄ってください。
pushStateの引数は1つ目から順に stateオブジェクト、タイトル、URL となっています。
- stateオブジェクト : 履歴のエントリと状態を結びつけるためのデータ。
その履歴に戻った時にページの状態を戻すための情報を格納しておきます。 - タイトル : MDN曰く、現在は無視されているパラメータ。将来的に使う事になるでしょう。
- URL : アドレスバーの表示を切り替える為のURL。
ちなみに replaceState というメソッドも実装されていて、同様の引数で利用できます。 こちらは履歴のスタックに push するのではなく、現在いるエントリを上書きするメソッドです。
ターゲットURL と ページ
指定したURLに実際にページが存在しない場合、 ページをブラウザでリフレッシュしたり改めてアクセスしたりすると Not found になってしまいますので、 実際にファイルを設置するか、mod_rewrite や サーバサイドのスクリプトでどうにかする必要があります。
あるいは、URLに “#foo” などを指定する事も出来ます。 これならば同じページで展開する事が出来ます…が、pushState である必要性が少し薄くなる気もします。
history.pushState({hash: "#foo"}, "", "#foo");
popstate イベント
location.hash における hashchange イベントと似た役割を持つのが popstate イベントです。
window.addEventListener("popstate", function(e){
e.state; // {url: "/foo"} など
}, false);
イベントハンドラに渡される Event オブジェクトには state オブジェクトがぶら下がっていますが、 これは pushState で設定した state オブジェクトです。 ここから情報を参照して、ページの状態を復元する事になります。
注意しなければならないのはイベント発火のタイミングです。 hashchange イベントは location.hash を変更した時点で発火しましたが、 popstate イベントは pushState をコールした時点では発火せず、 次の方法で「履歴を移動した時点」で発火します。
- ページロード時
- ブラウザの「戻る」「次へ」ボタンや、そのショートカットキーで移動
- history.go/back/forward() で移動
要するに、popstate イベントは pushState 以外の操作で履歴を移動した場合にページをその履歴の時点の状態に戻す為に使用するイベントだ、という事です。
これらの機能を使いつつ Ajax と連携してコンテンツを遷移する “pjax” という手法もありますが、それはまた別のお話。
コメント