連載:jQuery Mobile入門

第5回 jQuery MobileでJavaScriptプログラミング ― グローバル設定とイベント ―

山田 祥寛
2012/05/17
Page1 Page2

jQuery Mobileのイベントを理解しよう

 jQuery Mobileで提供されるイベントは、ごく大まかには「ページ・イベント」「タッチ・イベント」「そのほか端末操作に関わるイベント」に分類できる。その中で、特にページ・イベントとタッチ・イベントは頻繁に利用することになるはずだ。本稿でも、この2点に絞って解説を進めていく。

ページ・イベントを理解する

 jQuery Mobileがページの描画/遷移に当たってさまざまな自動処理を行っていることは、これまで何度も述べてきた。そして、これら自動処理を手軽にカスタマイズするのがグローバル設定の役割だったわけだ。

 もっとも、グローバル設定は、あくまでjQuery Mobileが想定する範囲内で、動作を切り替えるにすぎない。自動処理の途中にアプリケーション独自の処理を挟みたいという場合には不向きだ。そのようなケースでは、ページ・イベントを捕捉し、独自の処理を組み込む必要がある。

 まずは、以下に主なページ・イベントを発生順にまとめておく。ページの初期表示時、遷移時、エラー時で、それぞれ発生するイベントも異なるので注意してほしい*4

*4 正確には、複数ページ構造やキャッシュが有効な場合など、前提となる条件によっても発生するイベントは変化する。

イベント名 発生タイミング 初期 遷移 エラー
pagebeforechange ページ変更の前* ×
pagebeforeload 新しいページをロードする前 ×
pagebeforecreate ウィジェットなどの初期化前 ×
pagecreate ウィジェットなどの初期化後 ×
pageinit ページの初期化が完了した後 ×
pageload 新しいページをロードした後 × ×
pagebeforehide 旧ページを非表示にする前 × ×
pagebeforeshow 新しいページを表示する前 ×
pageremove 旧ページが文書ツリーから削除された後 × ×
pagehide 旧ページを非表示にした後 × ×
pageshow 新しいページを表示した後 ×
pagechange ページ変更が完了した後 ×
pageloadfailed ページ読み込みが失敗した場合 × ×
pagechangefailed ページ変更に失敗した場合 × ×
主なページ・イベント(○、×は発生するかどうかを表す)
* pagebeforechangeイベントは、ページ遷移時にはpageloadイベントの後にもう一度発生する。

 ページ・イベントの中でも、特によく利用するのがpageinitイベントだ。jQueryに慣れてきた読者にとって、ページの最初に行うべき処理を記述する場所といえば、まず$(document).readyメソッドが思い浮かぶかもしれない。しかし、前述したように、jQuery Mobileではreadyメソッドを利用する局面はごく限定的となる。

 というのも、jQuery Mobileではページ遷移をAjax通信によって行うためだ。readyメソッドは文書ツリーが完成したタイミングで実行されるもので、Ajax通信による読み込みによっては発生しないのだ。

 代わりに、jQuery Mobileではページ・イベントを利用しなければならない。どのような処理を行うかによって、どのイベントを利用すべきかも変動するが、一般的にはページが完全に初期化された(=文書ツリーが完成した)タイミングで発生するpageinitイベントが、$(document).readyメソッドに相当する処理を記述するのに適している。

 以下では、ページ・イベントを登録する方法を、いくつかのケースに応じて示しておく。

(1)全てのページに共通の処理を追加する場合

 $(document).bindメソッドを利用すればよい。例えば、以下は全てのページを開いたタイミングで、ダイアログ・ボックスを表示する例だ。

$(document).bind('pageinit', function(e, d) {
  window.alert('ページが呼び出されました!');
});
全てのページでダイアログ・ボックスを表示するコード(event.js)

(2)ページ固有の処理を追加する場合

 $(ページ要素).liveメソッドを利用すればよい。例えば、以下は「id="index"」であるページ要素でだけpageinitイベント・リスナを実行する例だ。

$('#index').live('pageinit', function(e, d) {
  window.alert('indexページが呼び出されました!');
});
「id="index"」であるページでのみダイアログ・ボックスを表示するコード(event2.js)

 liveメソッドは、将来的に追加される要素に対してもイベント・リスナを登録するためのメソッドだ。よって、あらかじめ上のようなコードを読み込んでおくことで*5、該当のページが文書ツリーに取り込まれたタイミングを正しく捕捉できるわけだ。

*5 一般的には、どのページからアクセスされるかは分からないので、全てのページで同じスクリプトをインポートするようにしておくことになるだろう。

[参考]データ・オブジェクト

 ページ・イベントのリスナでは、第2引数としてデータ・オブジェクトを受け取る。イベント・リスナでは、データ・オブジェクトを介することで、イベントに関する情報(新旧ページのURLやページ・ロード時の動作オプション、結果ステータスなど)を参照できるわけだ。本文のサンプルであれば、引数「d」がデータ・オブジェクトである。

 データ・オブジェクトでアクセスできる情報はイベントによって異なる。各イベントのデータ・オブジェクトが提供するプロパティの詳細は「jQuery Mobileのデモ&ドキュメント」の「Events」ページ(英語)を参照されたい。

補足:ページ・イベントの使いどころ

 ページ・イベントは、その種類の多さがゆえに、なかなか使い分けが難しい代物だ。もちろん、まずはpageinitイベントの利用を基本として、うまく結果が反映されない場合には利用するイベントを変更するという方法もないわけではない。しかし、主なものについて、その利用例を頭に入れておくのは無駄なことではないはずだ。

 以下に、比較的よく利用すると思われるページ・イベントについて、その用途をまとめておく。

イベント 利用例
pagebeforeload Ajax通信の挙動をカスタマイズする
pagebeforecreate オリジナルの文書ツリーに対する操作(data-xxxxx属性などの付与)
pagecreate ウィジェットによる文書ツリーの操作
pageinit 完成した文書ツリーに対するアプリケーション固有の操作
pageremove ページ削除によって不要になったリソースの破棄
pageloadfailed カスタムのエラー・ページへのリダイレクト
よく利用するページ・イベント

 jQuery Mobileでは、pagebeforecreateイベントの後で文書ツリーにさまざまな要素/属性を付与し、ウィジェットの適用に備えている*6。よって、data-xxxxx属性を動的に付与し、ウィジェットに反映させたいならば、このタイミングで行わなければならないわけだ(もちろん、後からdata-xxxxx属性を付与し、手動でウィジェットを再適用しても構わない)。

*6 例えば第3回の開閉パネルの出力(jQuery Mobileによってラップされた後のコンテンツ部のコード)などを参照してみるとよい。

タッチ・パネル固有のイベントを活用する ― タッチ・イベント

 デスクトップ・パソコンに代表されるマウス環境と、スマホのようなタッチ・パネル環境では、性質上さまざまな相違点があるが、その中でも特に顕著なのが、発生するイベントだ。例えば、タッチ・パネルでは「タップ(tap)」「スワイプ(swipe)」と呼ばれるマウスの「クリック」「ドラッグ」に相当するイベントが発生する。

 jQuery Mobileでは、こうした違いを開発者が最大限意識しなくても済むように、さまざまなカスタム・イベントを提供している。

イベント名 発生タイミング
tap 要素をタップしたとき
taphold 要素をタップした後、そのまましばらく指を離さずにおいたとき
swipe 要素をスワイプしたとき
swipeleft 要素を左方向にスワイプしたとき
swiperight 要素を右方向にスワイプしたとき
主なタッチ・イベント

 これらイベントの特徴は、タッチ・パネル環境だけではなく、マウス環境でも動作するという点だ。例えば、tapイベントであればマウス・クリックによっても発生するし、swipeイベントであればマウス・ドラッグによっても発生する*7。jQuery Mobileがマウスの対応する動作をマッピングしているのだ。

*7 tapholdイベントすら、(あまり一般的ではないものの)マウスをクリックしてしばらく動かさずにいることで発生させることができる。

 例えば以下は、左スワイプ時にafter.htmlに、右スワイプ時にbefore.htmlにページ遷移する例だ。サンプルをAndroid環境、Google Chrome(デスクトップ環境)で動かし、いずれの環境でもスワイプ、またはマウス・ドラッグによってページが遷移することを確認してほしい。

<script src="./swipe.js"></script>
……中略……
<div id="basic" data-role="page" data-title="jQuery Mobile入門">
  <div data-role="header" data-position="fixed">
    <h1>jQuery Mobile入門</h1>
  </div>
  <p>
    左右にスワイプしてください。
  </p>
  <div data-role="footer" data-position="fixed">
    Copyright 1998-2012, WINGS Project
  </div>
</div>
$('#basic').live('swiperight', function(){
  $.mobile.changePage('before.html');           *
});
$('#basic').live('swipeleft', function(){
  $.mobile.changePage('after.html');            *
});
スワイプ時に前後ページに移動するコード(上:swipe.html、下:swipe.js)
* $.mobile.changePageは、JavaScriptコードからAjax式リンクを発動させるメソッド。詳しくは、次回あらためて解説の予定である。

右にスワイプする
右にスワイプする
実行結果(上:Android環境、下:Google Chrome環境)

 なお、jQuery Mobileではスワイプをスワイプであると判断するための閾値(いきち)を、グローバル設定で定義することも可能だ。具体的に設定できるのは、以下の項目。

プロパティ スワイプと認められる条件 デフォルト値
durationThreshold 指定時間以内で動いた場合 1000ms
horizontalDistanceThreshold 指定距離「以上」、水平方向に動いた場合 30px
verticalDistanceThreshold 指定距離「未満」しか垂直方向に動かなかった場合 75px
スワイプの閾値を決めるグローバル設定
プロパティ名は「$.event.special.swipe.xxxxx」の「xxxxx」の部分で表している。

 一般的には、これらの値を変更することはあまりないはずだが、レイアウトなどの事情でスワイプ動作が正しく認識されないようなケースでは、これらの値を調整してみるとよいだろう*8

*8 ただし、標準の設定からあまり大きく変更すべきではない。ユーザーが考えるスワイプと、実際のそれとがあまりに食い違っていると、直感的な操作の妨げになるためだ。

 なお、horizontalDistanceThresholdプロパティは水平方向に動くべき「最小」距離を示すのに対して、verticalDistanceThresholdプロパティは垂直方向に動いてもよい「最大」距離を表す(要は、前者はタップの際の指のわずかなブレをスワイプと見なさないための、後者はスクロール動作とスワイプ動作とを区別するためのプロパティということだ)。意味が逆になるので、混乱しないように注意してほしい。

 以上、今回はjQuery MobileにおけるJavaScriptプログラミングの基礎について解説した。jQuery MobileはjQueryをベースにしていることから、jQueryを理解している諸氏にとって新しく覚えなければならないことは、それほど多くはない。しかし、jQueryで慣らされてしまったばかりに間違えやすい、jQuery Mobile固有の注意点もある(特にreadyメソッドの扱いがそれだ)。これまであまり意識してこなかったという方は、いま一度、jQuery Mobileにおける自動初期化やAjax式リンクなど、内部的な挙動にも関心を向けておくことをお勧めする。

 次回は、JavaScript API編の続きとして、フォーム要素をはじめとするウィジェットの操作について解説の予定である。end of article


 INDEX
  [連載]jQuery Mobile入門
  第5回 jQuery MobileでJavaScriptプログラミング ― グローバル設定とイベント ―
    1.jQuery Mobileの動作をカスタマイズしよう ― グローバル設定
  2.jQuery Mobileのイベントを理解しよう

インデックス・ページヘ  「連載:jQuery Mobile入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH