こんにちは。
pushStateやpopStateというHTML5 HISTORY APIをご存知でしょうか。
もともとhistory APIは前からあり、history.back();
などでブラウザの戻る
と同じ挙動をさせることができます。
今回はHTML5で追加されたpushStateとpopStateに注目していきましょう。
よくAjaxなど、画面遷移を伴わずコンテンツなどの入れ替えを行う際に活用されています。
Facebookの例
※個人情報の観点からスクリーンショットがご用意できずすみません。
メッセージページでは左側にメッセージのやり取り相手の写真が並びます。
それらをクリックすることによってメインのやり取りが表示されていくことになります。
そのとき、URLを注目してみると…
https://www.facebook.com/messages/nagatasan
であったり、
https://www.facebook.com/messages/san.nagata
という風に変わっているのが分かります。
また、戻るボタンの挙動は、それらをちゃんと戻っていく動きです。
どうなってるの?
画面遷移を行う(index.htmlからpage.htmlにファイルを移動するなど)場合はブラウザのヒストリーとして残るのが標準です。そして戻るボタンはそのヒストリーを戻っていくわけです。
しかしながら画面遷移を行わない場合は、デフォルトでそのようなことをしてくれません。
なので、明示的に行う必要があるのです。
実際の実装コードをみていきます。
if( window.history && window.history.pushState ){
window.history.pushState(state,title,url);
}
javascriptでAPIを操作します。
- まず最初の
if
ではpushStateに対応しているかどうかを確認します。(モダンブラウザでないと、対応していないものもあり、その場合は別途JSなどで実装する方法があります) window.history.pushState(state,title,url);
というところでURLの変更やStateの保存をしていきます。ノンプログラマの方には馴染みがないかもしれませんが、push/popはそもそもスタックという考え方で、データ格納/データ取り出しの後入れ先出しという理解で問題ないかと思います。- state:状態と関連付けされた情報を格納できます
- title:タイトルです
- url:ブラウザのバーに表示されるURLです(実際に遷移するわけではないので、関係のない値をいれてもリダイレクト等はできません)
という流れがpushState
の使い方になります。
これだけでもURLが変動していき、戻るボタンをするとそれぞれその履歴に応じて戻っていくことができます。
具体的な使い方
さて、それではどういったときに活用できるかご紹介します。
ここからはpopState
も使っていきます。
タブメニューがあるページ
ページ自体は遷移せず、タブメニューで情報整理をしているページってありますよね。
そんなときはタブ移動のclickイベントなどと合わせてpushState
を行い、戻るボタンではpopState
を用いて挙動を書くことになります。
$('tabMenu').click(function(){
var nextTab = $(this).next();
openTab(nextTab);
window.history.pushState(nextTab,null);
});
$(window).on('popstate', function(jqevent) {
var state = jqevent.originalEvent.state;
if (state) {
openTab(state);
};
});
という感じです。popState
で戻るボタンのイベントを取得し、もしpushState
していたものがあれば該当するタブを開きます。
画面遷移はしていないのに、タブの遷移を戻るボタンにひもづけることができますね。
※jQueryでサンプル書いてますが、ピュアJSでも書くことができます。
アンカーやハッシュタグ、パラメーターを使っているページ
こちらも考え方は同じですが、pushState
の第3引数:URLまで指定しています。
$('nextButton').click(function(){
var nextContent = $(this).next();
goContent(nextContent);
window.history.pushState(nextTab,null,"#"+nextContent);
});
$(window).on('popstate', function(jqevent) {
var state = jqevent.originalEvent.state;
if (state) {
goContent(state);
};
});
#hogehoge
の他に、?param=hogehoge
なども可能ですね。
ハッシュタグの場合、hashchange
というものを使うこともできます。
まとめ
いかがでしたか?
ページは遷移していないにも関わらずコンテンツが大きく変動するイベントの場合、ついつい利用者としては戻るボタンクリック(Macであればスワイプであったり)をしてしまいがちです。
「あー、そこまで戻るつもりじゃなかったんだよ」という不満を生まないためにも、ユーザーに配慮した挙動を考えると、デキる実装なんじゃないでしょうか!
ちなみに今日は本ブログを書きながら、弊社サービス「universions」にて画面遷移しないけどコンテンツが変わっていくページに、取り入れてみました。
是非御覧ください。
Web制作のファイル管理ツール「universions」
バージョン管理ができて、いつでも最新版を確認できるWebサーバーも提供中。
制作からテスト、公開までWeb制作のフローを完璧にサポートし、1人の作業も複数人での協業も円滑になります。