Edited at

16行 で pushState popState

More than 5 years have passed since last update.


2013/12/27 追記:初回アクセス時に popState イベントが発生しリロードしてしまう問題への対策を記載しました。(この追記により、タイトルが 15行 → 16行 に変更になりました^^)



pushState popState とは

Ajax を使ったスムーズな画面遷移でも、URL を書き換え履歴に追加し、ブラウザバックに対応することができる仕組みです。SEO への影響を出すこと無く操作性を向上させることができます。

現在、pushState/popState を使ったクライアントサイドルーティングを実現するライブラリがいくつか作られていますが、今回は jQuery だけで行うシンプルな方法を紹介します。

参考: Googleに続いてBingもAjaxにはpushStateを推奨


本題

jQuery だけで、15行程度でできる pushState popState を使った Ajax 画面遷移の方法です。

if (window.history && window.history.pushState) {

// 内容の読み込み処理
function loadContents(url) {
$.get(url, { push_state: 'true' })
.then(function(content) { $('#main').html(content); });
}

// pushState を使った遷移
$(document).on('click', '.push-state', function(e) {
e.preventDefault();
var url = $(this).attr('href');
loadContents(url);
history.pushState('', '', url);
});

// popState イベントをハンドリング
$(window).on('popstate', function(e){
if (!e.originalEvent.state) return; // 初回アクセス時に再読み込みしてしまう対策
loadContents(location.pathname);
});

}


内容の読み込み処理

ページの内容を Ajax で読み込んで反映する処理です。

サーバサイドに pushState による画面遷移であることを通知する必要があるなら、 pushstate: 'true' などのパラメタを渡します。または、サーバサイドで HTTP_X_REQUESTED_WITH パラメタを検出するという方法もあります。

読み込んだら、所定のコンテナ 例では <section id="main"></section> 等 に上書きします。


pushState を使った遷移

ハイパーリンクやボタンをクリックした際に、通常の画面遷移をキャンセルして内容の読み込みと pushState へのURL変更登録を行います。

上記の例では、 class="push-state" 属性がついた a タグに反応するようになります。


popState イベントをハンドリング

最後に「戻るボタン」「進むボタン」がクリックされた時の処理を定義します。

これは単純に、現在の URL を使って内容の読み込みを行うだけです。

ただ、popState イベントは 初回アクセス時にも発生してしまいます。

そのため e.originalEvent.state を使って、まだ pushState されていなければなにもしないという対策が必要となります。