なんかそれっぽいのを作りました。
いろんなところが全然スマートじゃないけど……。
解説
まず、それぞれのページを以下のようにマークアップします。
Bootstrap Modalを前提にしているので、その辺のスクリプトが動くようにBootstrapとかjQueryとか読み込んでください。
モーダルの親
HTML
<!-- 前略 -->
<script src="/demo/modal/pushstate/js/modal_common.js"></script>
<div id="container">
<div id="article">
// コンテンツを入れます。
<a class="js-modal" href="modal.html">モーダルを開く</a>
</div>
<div id="modal-content">
<div class="modal fade" id="myModal">
<div id="modal-dialog" class="modal-dialog">
// 何も入れません。ただの受け皿。
</div>
</div>
</div>
</div>
<!-- 後略 -->
モーダルウィンドウを開くaタグに、「js-modal」クラスとモーダルのURLを記述します。
モーダル
HTML
<!-- 前略 -->
<script src="/demo/modal/pushstate/js/modal_common.js"></script>
<script src="/demo/modal/pushstate/js/modal_reload.js"></script>
<div id="container" data-parent="/demo/modal/pushstate/index.html">
<div id="article">
// 何もいれません。
</div>
<div id="modal-content">
<div class="modal" id="myModal">
<div id="modal-dialog" class="modal-dialog">
// モーダルで表示するコンテンツを入れます。
</div>
</div>
</div>
</div>
<!-- 後略 -->
ここで大事なのは、#containerのdata属性に、モーダルの親のURLをモーダルに持たせることです。
HTML
<div id="container" data-parent="/demo/modal/pushstate/index.html">
data-parentの値にモーダルの親のURLが埋め込まれていると、モーダルに外部からアクセスしてきたときに、#articleの部分にモーダルの親の内容を入れてくれて、モーダルを閉じても (前のページに戻っても) ページが真っ白にならずに親のURLに戻るようになっています。
モーダルの中に別のモーダルへのリンクを設置することもできます。
HTML
<!-- 前略 -->
<div id="modal-content">
<div class="modal" id="myModal">
<div id="modal-dialog" class="modal-dialog">
// モーダルで表示するコンテンツを入れます。
<a class="js-modal" href="modal_b.html">別のモーダルを開く</a>
</div>
</div>
</div>
<!-- 後略 -->
その他
- history.back()とhistory.forward()にも対応してます。
- 次のページが無かった場合にhistory.forward()したときは、forwardを停止するようになっています。
終わりに
pushStateのページ遷移はよく見るんですが、USA TODAYみたいなモーダルウィンドウを実践している人は多分いなかったので、pushStateの勉強も兼ねて作りました。
未だによく分かってない部分もありますが、何かそれっぽく出来たなー、という感じでGithubにぶっこんでみました。
不具合等ございましたら、ご一報頂けますと幸いです。
2016/01/19 追記
色々バグってたり処理が不足していたので、アップデートしました。
詳しい実装方法はGithubに書いています。