読者です 読者をやめる 読者になる 読者になる

はじめての jQuery Mobile 1.0 〜その2:ページ遷移〜

JavaScript


はじめての jQuery Mobile 1.0 〜その1:コンテンツの記述〜 - etc9からの続きです。

ページ遷移時のイベント

jQuery Mobile では、1つのHTMLファイルに複数のページビューを定義できます。外部ページも非同期リクエストにて取得したページビューを、既存の DOM に挿入することでページ遷移を実現します。
これによりページ遷移の度にサーバへのリクエストを行うこと無く、通信帯域の制限されたモバイル環境においてスムーズなページ遷移を可能にしています。


このような特徴があるため、jQuery Mobile では $(document).ready() といった、ページロード時のイベントと、ページ遷移(表示)時のイベントを区別して扱う必要があります。


ページの初期化には pageinit イベントを使う

ディスクトップ向けに jQuery を利用する場合は、$(document).ready() にて DOM の読み込み完了後に処理を実行することが一般的です。しかしjQuery Mobile では、ページ遷移は Ajax にて行われるため、ready イベントは最初にページを読み込んだ時にしか呼び出されません。

jQuery Mobile では、ページ初期化時のイベントには、pageinit を利用することが推奨されています(ベータ版では pagecreate を使っていたが、現在は初期化コードは pageinit で行うのが最適となっている)。pageinit を使う事で、内部ページがロードされた時、Ajax によるナビゲーションで読み込まれて他のページの内部にコンテンツが挿入された時の処理方法を定義することができます。


pageinit イベントの実行タイミングは分かりにくいので多少詳しめに説明します。
以下のようなページビュー(page1 と pate2)が2つ定義した sample.html があるとします。

・・・
<section id="page1" data-role="page">
  <div class="content" data-role="content">
    <p><a href="#page2">Go To Page 2</a></p>
    <p><a href="external.html">Go To Page External Page 3</a></p>
  </div>
  <footer data-role="footer"><h4>Page Footer</h4></footer>
</section>

<section id="page2" data-role="page" data-add-back-btn="true" >
  <div class="content" data-role="content">
    <p><a href="#page1">Back To Page 1</a></p>
  </div>
</section>
・・・

page1 には、外部ページとして page3 へのリンクがあり、external.html は以下の定義とします。

・・・
<section id="page3" data-role="page" data-add-back-btn="true">
  <header data-role="header"><h1>Page 3</h1></header>
  <div class="content" data-role="content">
    <p><a href="#page1">Back To Page 1</a></p>
  </div>
</section>    
・・・

page1 と page2 は内部ページで、page3 は外部ページの状態です。


sample.html に pageinit イベントを処理する以下のようなコードがあるり、

$(document).ready(function() {
  alert('ready');
  $("#page1").bind("pageinit", function() {
    alert('Page1 pageinit event');
  });
  $("#page2").bind("pageinit", function() {
    alert('Page2 pageinit event');
  });
  $("#page3").live("pageinit", function() {
    alert('Page3 pageinit event');
  });
});

page1 → page2 → pate3 → page1 → page2 → pate3 の順番でページ遷移すると、

  1. alert('ready') の実行
  2. page1の表示
  3. alert('Page2 pageinit event')の表示
  4. page2の表示
  5. alert('Page3 pageinit event')の表示
  6. page3の表示
  7. page1の表示
  8. page2の表示
  9. alert('Page3 pageinit event')の表示
  10. page3の表示

のようになります。


page2 → pate3 → page1 の順番でページ遷移(page2を初期表示)すると、

  1. alert('ready') の実行
  2. page2の表示
  3. alert('Page3 pageinit event')の表示
  4. page3の表示
  5. alert('Page1 pageinit event')の表示
  6. page1の表示

のようになります。


つまり、ready() 内にて pageinit イベントをバインドした場合、初期表示ページ用の pageinit イベントは実行されない。内部ページへの遷移時には、初回表示時のみ pageinit が処理される。外部ページへの遷移時には、pageinit が毎回処理される。ということになります。
注意点としては、外部ページを指定したイベントのバインドは、bind() ではなく live() にて行う必要があるということです。


結局のところ pagiinit は

ready() の外で、live() か delegate() でバインドしてあげるのが良さそうです。

とすると、全てのページの初期表示時のみ(page3は毎回) pageinit の処理が実行されます。(最初のページは pageinit → ready のイベントの順番)


ページ切替イベント

ページ遷移を行う場合に利用できる、遷移元と遷移先のページの表示・非表示に対応するページ切替イベントがあります。これらのイベントを処理することで、ページ遷移時の挙動を細かく制御することができます。
以下にページ切替のイベントを示します。

  • pagebeforehide :ページ遷移前に遷移元のページ上で発生
  • pagebeforeshow :ページ遷移前に遷移先のページ上で発生
  • pagehide :ページ遷移の完了後に遷移元のページ上で発生
  • pageshow :ページ遷移の完了後に遷移先のページ上で発生


先ほどの例と同様に、内部ページ遷移のイベントには bind() を利用し、外部ページ遷移のイベントには delegate() または live() を使用してイベント発生時の処理を登録します。


各コールバックでは第2引数にて遷移元、または遷移先ページを示すオブジェクトが得られます。

$('div').live('pageshow', function(event, ui) {
  alert('This page was just hidden: ' + ui.prevPage);
});

$('div').live('pagehide', function(event, ui) {
  alert('This page was just shown: ' + ui.nextPage);
});

ダイアログページ

ページビューへの画面遷移は、リンクに data-rel="dialog" 属性を付けることで自動的にダイアログ表示となります。

・・・
  <p><a href="#page2" data-rel="dialog">Go To Page 2</a></p>
・・・

上記リンクから遷移したページは以下のようにモーダルダイアログ形式にて表示されます。


ページ遷移方法

jQuery Mobile にはページ遷移時のアニメーションがいくつか用意されています。遷移時のアニメーションはリンクの属性にて data-transition 属性にて指定します。以下の値が指定可能です。

  • slide:現在のページの横から新しいページがスライドして表示される
  • fade:現在のページに新しいページが徐々に表示される
  • flip:現在のページが回転して背面にあるページが表示される
  • pop:現在のページの中央から新しいページが飛び出して表示される
  • slidedown:現在のページの上部から新しいページがスライドして表示される
  • slideup:現在のページの下部から新しいページがスライドして表示される
  <p><a href="#page2" data-transition="flip">Go To Page 2</a></p>


アニメーションを逆方向の効果として利用するには、data-direction="reverse" を指定します。
例えば、上記の flip を指定したページに戻るリンクを以下のように指定すると逆回転の flip で元のページに戻る効果が得られます。

  <p><a href="#page1" data-transition="flip" data-direction="reverse">Back To Page 1</a></p>

プログラムからのページ遷移

プログラム的にページ遷移を発生させるには、$.mobile.changePage メソッドを使います。
例えば、page1に遷移後、1秒後に自動的にpage2に遷移させたりすることができます。

$("#page1").live("pageshow", function() {
  setTimeout(function() {
    $.mobile.changePage("#page2", { transition: "slideup"});  
  }, 1000);
});

changePage の第一引数には、文字列として遷移先の URL を指定するか、$("#about") のように jQuery オブジェクトを指定します。第二引数にはオプションをハッシュで渡します。

フォームのデータをPOST送信する場合、

$.mobile.changePage( "searchresults.php", {
	type: "post", 
	data: $("form#search").serialize()
});		

popの効果で、履歴(プラウザの訪問履歴)に残さない遷移の場合、

$.mobile.changePage( "../alerts/confirm.html", {
	transition: "pop",
	reverse: false,
	changeHash: false
});


など、様々なオプションがあります。詳しくは公式ドキュメントを参照してください。


はじめての jQuery Mobile 1.0 〜その3:リストビュー〜 - etc9に続く...