jQueryMobileのページ関連イベントの発生タイミングでちょっとはまる

2011年12月5日

スマートフォン用サイトを、jQueryMobileを使って開発している時にはまった事柄のメモ。分かってしまえばなんでも簡単。

$(document).ready()の代わりに使うというイメージ?

ブラウザ上にページが表示されるタイミングで色々と細工をしたいという場合、jQueryを使うならば

$(document).ready(function(){
//処理
});

なんて風にする。
ありきたりな手法だ。

jQueryMobileでは、それの代わりに

$(ページのセレクタ).live( "pageshow", function(){
//処理
});

といった具合に記述する、といった約束みたいなのだけど、これがうまく動かなかった。

うまくいかないというのは具体的にどういうことか

「うまくいかない」というのは便利な言葉で、それは具体的にどういうことですか?という質問をしなくてはならず、場合によってはうまくいかなくてイライラしている人を怒らせてしまったりもする。
思ったように動かないということだけは分かるんだけど、もうちょっと情報が欲しいということは珍しいケースではない。

今回は、A.html からB.html に遷移して、B.htmlのページが表示されるタイミングで動いて欲しかったわけなんだけど…動いてくれなかったわけです。

B.htmlのソース中に

$(ページのセレクタ).live( "pageshow", function(){
  alert('hogehoge');
});

と書いておけば、B.html のページが表示されるタイミングでアラートダイアログがあがるハズ…なんだけどあがらない、という。

ページをリロードすると動く

見出しの通り。

何故かページをリロードすると動いてくれるということに気づいた。最初は動いたり動かなかったりするんだよなぁ…という具合だったわけで、色々やっていくうちに「どうやらリロードすると動くみたいだ」と。何事も粘り強く続けることが肝心だ。

ということは

jQueryMobileは、ajaxを使って遷移先のページのソースを読み込んで表示する仕組みだ。
なので、javascriptの評価もページのソースを読み込む前にしておかないといけないんじゃないか?と考えた。

リロードしたら動くというのは、つまりそのページがjQueryMobileとして最初のページなので、その場合だけソース読み込み後にjavascriptが評価されているんじゃないか?と。

つまり

$(ページのセレクタ).live( "pageshow", function(){
//処理
});

は、該当ページ中に書くのではなく、遷移前のページに書いておく必要があるということ。実際それで問題無く動いた。
遷移の流れは複数になったりするので、それぞれのページの動作を1つの外部ファイルにまとめて、常にそれを読み込むようにした。
当然のことながら、ページのセレクタはhtmlファイルを跨いで遷移する全部のページを一意にしておかないとおかしなことになる。

分かってしまえば、すごく簡単な話。

WAPっぽいですね

EZweb初期のマークアップ言語はchtmlでは無く、WAP(Wireless Application Protocol)というものだった。
これはchtml何かと違って、1ファイルに複数ページが書けるもので
 ページ遷移時に読み直しをしないでもいける=通信が遅くてもそこそこ大丈夫
という仕様だった。

jQueryMobileも何となくその手法に近くて、それを利用することでアプリケーションっぽい動作が出来るわけなんだけど、それが1ファイル内完結の仕組みではなく、全体として1つのアプリケーションを構成するようになっています、ということみたいだ。

繰り返すけれど、分かってしまえば何てことはない。ただちょっと頭の切り替えをしないとおかしな感じで躓きますね、という話。