ブラウザの履歴を操作する
HTML5のHistory APIを使うと、ページ遷移を行わずにJavaScriptでブラウザの履歴を操作できます。この仕組みを利用すると、Ajaxでコンテンツを変更しつつ、通常のページ遷移と同じように履歴を追加することができます。ブラウザの戻るボタンも問題なく使用できます。URLの#を使う方法と比べてURLがすっきりするのでユーザーにとって馴染みやすく、またAjaxコンテンツにおける_escaped_fragment_のような特別なURLを用意する必要がないという利点があります。History APIはIE6から9までのブラウザではサポートされていません。
実際に使われている例として、GitHubのプロジェクトのファイル一覧ビューはHistory APIが利用されており、部分的にコンテンツを読み込んで表示し、ページ全体は読み込まずにURLを変えています(図1)。
History APIはサポートされているブラウザ間でも多少挙動に違いがありますが、History.js(BSDライセンス)というライブラリを使うことでブラウザごとの違いを吸収できます。
History.jsの使い方
History.jsは、History APIがサポートされていないブラウザではURLの#以降を使って代替する機能を持っており、任意で有効にすることもできますが、URLにIDが自動的に付加されるなど多少見苦しいものとなってしまいます。ここで紹介する使い方は、History APIが使える場合はそれを活用し、History APIが使えない場合は通常のリンクでページ遷移するという手法です。
まずjQuery用のHistory.jsライブラリをここからダウンロードします。このファイルをjs/libs/jquery.history.jsに設置したものと仮定します。JSONの節で紹介したjson2.jsもjs/libs/json2.jsに置いておきます。そして、リスト3のHTMLを作成し、リスト4のスクリプトをjs/main.jsとして読み込みます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<div id="main">
<a href="1.html" id="link1">link1</a>
<a href="back.html" id="back">back</a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="js/libs/json2.js"></script>
<script src="js/libs/jquery.history.js"></script>
<script src="js/main.js"></script>
</body>
</html>
if History.enabled # History APIが有効な場合
# History.jsによって状態が遷移した時に呼ばれるコールバック
History.Adapter.bind window, 'statechange', ->
state = History.getState()
console.log "statechange"
console.log state
# 元となるpushStateに関する情報がstateに入っている
# state.data pushStateの第1引数
# state.title pushStateの第2引数
# state.url 遷移先のURL
# ここでstate.urlに該当するURLのコンテンツをAjaxで取得して表示する
# id="link1" の要素をクリックした時に呼ばれる
$('#link1').click (event) ->
# History.jsが有効になっていない時は通常通りページ遷移させる
if not History.enabled
# trueを返すとクリックイベントが通常通り処理される
return true
# 状態を遷移させ、ページの履歴に追加する
History.pushState { abc: 123 }, 'Page 1', '1.html'
# falseを返すとクリックイベントがキャンセルされる
false
# id="back" の要素をクリックした時に呼ばれる
$('#back').click (event) ->
history.back() # 履歴を1つ戻る
false
このページをブラウザで開き「link1」をクリックすると、1.htmlというファイルが存在していなくてもブラウザのURLを1.htmlに変えることができます。
History.pushState(data, title, url)を実行するとブラウザのURLが変わり、履歴が追加されます。引数は次の通りです。
-
History.pushState(data, title, url)
- data:遷移先に渡すオブジェクト(nullまたはオブジェクト)
- title:遷移先のタイトル(nullまたは文字列)
- url:遷移先のURL(文字列)
履歴を1つ戻るにはhistory.back()を呼びます。この場合はすべて小文字のhistoryを使うことに注意してください。このhistoryオブジェクトの正体はwindow.historyで、history.back()はHTML5以前からブラウザに標準でサポートされている機能です。履歴を2つ前まで一気に戻る場合はhistory.go(-2)を呼びます。
history.back() # 1つ前に戻る history.go -2 # 2つ前に戻る history.go -3 # 3つ前に戻る

