2015年6月3日水曜日

[HTML5] pushStateでajaxアプリでもブラウザ履歴を使ってみるサンプル

pushState はブラウザに履歴を追加するHTML5のAPIです。pushState を利用すれば、ajaxを多用しているページでもブラウザの「戻る」「進む」ボタンを使って自然な履歴操作を実現することができます。
以下は pushState を利用して擬似的な画面遷移を実現するサンプルアプリです。

まずはダミーのAPIを用意しておきます。

api1.json
{ "msg": "hello1" }

api2.json
{ "msg": "hello2" }

そして下がpushStateを利用するhtmlです。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>HTML5 pushStatus example</title>
    <script type="text/javascript" src="jquery-2.1.0.min.js"></script>
  </head>
  <body>
    <h1 id="title"></h1>
    <div id="content"></div>
    <nav>
      <ul>
        <li><a href="/api1">api1</a></li>
        <li><a href="/api2">api2</a></li>
      </ul>
    </nav>
  </body>
  <script>
  $(function() {

    $('nav a').click(function(e) {
      e.preventDefault(); // stop the default click stream
      var nextPage = $(this).attr('href');
      changeContents(nextPage);
      window.history.pushState(null, null, nextPage);
    });

    function changeContents(api) {
      var url = api + ".json";
      $.get(url, function(data){
        $("title").html(api);
        $("#title").html(api);
        $("#content").html(data.msg);
      }); 
    }

    // called on clicking back/forward button on browser's toolbar
    onpopstate = function(e) {
      changeContents(location.pathname);
    }

  });
  </script>
</html>

■コードのポイント

$('nav a').click(function(e) {
  e.preventDefault();
  ...

↑ここでリンクがクリックされたときのブラウザの通常の画面遷移を中断させて

window.history.pushState(null, null, nextPage);

↑でブラウザ履歴に現在のURLを追加しています。

// called on clicking back/forward button on browser's toolbar
onpopstate = function(e) {
  changeContents(location.pathname);
}

↑ここはブラウザの「戻る」/「進む」ボタンが押された時に呼ばれます。contentChange関数に location.pathname を渡して変更箇所を再描画しています。

実行


それでは早速Webサーバを立ち上げて、、、

$ python -m SimpleHTTPServer

http://localhost:8000 にアクセスして試してみましょう。
画面に表示された api1 や api2 リンクをクリックすると、ajaxで画面遷移無しに(サーバサイドへのリクエスト無しに)画面が変化しますが、ブラウザ履歴はちゃんと残っているのでブラウザからの「戻る」や「進む」もできます。

以上で、「ブラウザ履歴が利用できるajaxなWebアプリ」ができました。pushStateの基本のキは理解できたでしょうか?

ただし、このままだとブラウザのアドレスバーからURLを直叩きされた時に Not Found になってしまいますので、サーバサイド側には非Ajaxなページ表示処理を仕込んでおく必要があります。(非Ajax向けのページ用意しておくことはSEO対策にもなります)

次回

今回は生のpushStateを使いましたが、実践ではpushStateを実装したjqueryプラグインの jquery.pjax.js を使うのが便利そうです。もちろんサーバサイドがpjaxに対応していなければあまり意味がありませんので、次回は、クライアントサイドに jquery-pjax を使いつつ、サーバサイドにはおなじみの express4 を使って簡単なWebアプリを作ってみたいと思います。

0 件のコメント:

コメントを投稿