※この記事は2013年6月26日に執筆された記事です。現在は仕様が異なる可能性があります。
モバイル用WEBアプリケーションやスマートフォンサイト制作用のフレームワーク「jQuery Mobile」
手軽にリッチなコンテンツを構築できる事で人気のフレームワークですが、ページ遷移の仕様についていくつか注意点があります。
今回はその問題点や改善方法をご紹介します。
目次
jQuery Mobileの特徴
スマートフォン向けのフレームワークは数多く存在していますが、jQuery Mobileの大きな特徴としては以下が挙げられます。
- クロスプラットフォーム対応(iOS、Android、Windows Phone、BlackBerry等)
- セマンティックなHTML記述による高いアクセシビリティ性
- HTML、CSSの知識があれば、簡単に構築が可能
- Dreamweaverでのモバイル開発機能追加
また、jQuery Mobileの特徴の一つとして、ページ遷移時のトランジション(アニメーション効果)が標準で機能されている点があります。
この機能はAjaxといって、非同期通信を利用して遷移先のデータを取得し、通信結果に応じて動的にページの内容を書き換えるという動きにより実現しています。
以下の章ではこのAjaxによるページの遷移方法とその問題点・解決方法についてご紹介致します。
Ajaxによるページ遷移の問題点
jQuery Mobileで使われているAjaxでのページ遷移ではCSS、jsファイルの読み込みを行っているHEAD部分はそのままで、BODY部分のみ置き換わる動きをします。
一見ページが切り替わったように見えますが、URLは#で繋がれ実際にはページ遷移をしていない状態なのです。
この仕様でのWEBサイト制作においては、下記のようなデメリットが存在します。
- 1ページ1HTMLという概念ではなくなるため、ページ固有のcss、jsが使えない(全ページ同じcss、jsを使用しないといけない)
- ページ個別での解析タグ(Google AnalyticsやAdSense等)を入れるには別途スクリプト追加による対処が必要
- HTMLのID重複に注意が必要
Ajaxで遷移先のデータを取得し現在のDOMに挿入する動きになるので、遷移元のページに同じIDを持つ要素があると、1つのDOM中に2つ以上の同じIDが含まれる事になってしまう。
IDが重複するために、jQueryなどでセレクタでの要素をうまく取得できない。
上記のような理由で、jQuery Mobileを使用したサイト構築にあたってはAjax遷移を無効化させる設定が必要なケースが多くあります。
一般的なAjax無効化の設定
公式サイトにも紹介されている下記の方法でAjax無効化を試してみます。
http://view.jquerymobile.com/1.3.1/dist/demos/widgets/links/
リンク属性にrel=”external”またはdata-ajax=”false”を追加する事でAjaxを使用しない遷移を設定する事ができます。
下記にて動作を確認してみてください。
ボタンのaタグに対して「属性を変更しない(Ajax有効のまま)」「属性を変更(Ajax無効)」をそれぞれ設定しています。
Ajax遷移時は最初に表示したページで指定しているスタイルが適用され背景色は変化しませんが、AjaxをOFFにする遷移では各ページで指定しているスタイルが適用され背景色が切り替わるようになります。
また、全てのリンク属性に上記指定を入れていくのが面倒な場合は共通のスクリプトとして下記のように全てのaタグの属性を変更するというような指定を入れて全ページで読み込ませるようにすると構築が楽になります。
$("a").attr({ "rel":"external" }); /*または*/ $("a").attr({ "data-ajax":"false" });
rel=”external” は、他のサイトへのリンクに用いられますが、data-ajax=”false” は同じサイト内であっても何らかの理由でAjaxによる遷移を行いたくないという場合に使います。
本記事のサンプルでは同じサイト内での遷移をメインとして、data-ajax=”false”を扱う事とします。
ブラウザ「戻る」操作によるページ遷移の不具合と対処方法
jQuery Mobileにはブラウザの「戻る」ボタン操作によるページ遷移の不具合があります。
それは、一度ページ遷移をした後にブラウザの「戻る」ボタンでページを戻ると次のページ遷移後に遷移元のページへ戻されるというものです。
これは特定のOSやバージョンによって起こる不具合のようで、
・iOS 4, Android 2.3
・jQuery Mobile 1.3.1
にて現象の再現を確認しています。
これは上記のAjax無効化を行っても起きてしまう現象で、これに追加して対処が必要になります。
上記サンプルはjQuery Mobileの初期設定でpushStateEnabledという属性を変更する方法で、head内のスクリプトの読み込み部分を下記のように指定します。
※注意:jQuery本体とjQuery Mobileのjsの間で指定をしないと動作しません。
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script language="JavaScript"> $(document).bind("mobileinit", function(){ $.mobile.pushStateEnabled = false; }); </script> <script type="text/javascript" src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
これによってAjax無効化を行いつつ、ブラウザの「戻る」操作による不具合も解消された形となります。
ダイアログの併用について
Ajaxを無効化し、全ページHTMLを分割したサイト構成であれば上記の対応で問題ありませんが、ユーザーのログイン操作や設定画面表示、注意書きなど、部分的にダイアログ(モーダルウィンドウ)を使用したい場面もよくあるかと思います。
jQuery MobileのダイアログはAjax遷移をするものなので、上記のように全てのリンク属性にAjax無効化をしているとダイアログとして設定したページも普通に遷移してしまいます。
その場合、上記の全aタグの属性変更をしていた箇所をこのように「ダイアログのリンクは除く」という指定に変更しておくと、通常のページ遷移はAjaxを無効、ダイアログはAjaxを有効という使い分けをする事ができます。
$("a").attr({ "data-ajax":"false" }); ↓ $("a:not([data-rel=dialog])").attr({ "data-ajax":"false" });
また、ダイアログを閉じるためのリンク指定を下記のようにし、別途スクリプトを用意する事でダイアログを閉じる動作をさせる事もできます。
ダイアログの閉じるボタン部分:
<a href="#" data-role="button" onclick="closeDialog();">閉じる</a>
スクリプト(関数)の指定:
<script> function closeDialog() { $('.ui-dialog').dialog('close'); } </script>
参照:jQuery Mobile公式サイト ダイアログページ
http://view.jquerymobile.com/1.3.1/dist/demos/widgets/dialog/
まとめ
今回はWEBブラウザで閲覧する”サイト”における一つの設定Tipsとしてご紹介しましたが、
PhoneGapのようなネイティブアプリケーションをビルドさせるアプリケーション開発においては「戻るボタン」自体の無効化などの制御もできるため、今回のようなハックが不要な場合もあります。
また、サイト規模やコンテンツの内容によっては、通常どおりAjax遷移やトランジション効果を生かして構築する事はもちろんあると思いますので、今回ご紹介した設定も一つのパターンとしてご活用頂ければと思います。