[[iPhone関連]] > [[iPhoneサイト構築]] > jQuery Mobile を使用してスマホサイト構築
* jQuery Mobile を使用してスマホサイト構築 [#h0e44747]
#setlinebreak(on);

&color(red){※TODO:書きかけの記事};

基本的な使い方は、以下のサイトを参照して構築するものとして、
当ページでは、特にデザインなどのカスタマイズ方法と、カスタマイズに必要な最低限の情報についてのみ記載する。
#html(<div style="padding-left:10px">)
http://jquerymobile.com/
http://dev.screw-axis.com/doc/jquery_mobile/
#html(</div>)

《目次》
#contents

** ページの基本構成 [#q7c60242]
#html(<div style="padding-left:10px;">)
デザイン面で重要になるのは、data-role などの data 属性
jQuery Mobile は指定された data-role などの属性を読み取り、各要素にCSSセレクタの付与などを行い、ページの体裁を整える。

また data-role="page" の要素は1ページ内に複数持つ事ができ、非同期通信による部分読み込みによって、
1枚のHTMLを複数ページであるかのように見せる事ができる。
#html(</div>)

 <html>
 <body>
 	<div id="page1" data-role="page">
 		<div data-role="header">
 			ヘッダ領域
 		</div>
		<div data-role="navbar">
 			ナビゲーションバー領域
 		</div>
 		<div data-role="content">
 			コンテンツ領域
 		</div>
 		<div data-role="footer">
 			フッタ
 		</div>
 	</div>
 	<div id="page2" data-role="page">
 		<div data-role="header">
 			ヘッダ領域
 		</div>
		<div data-role="navbar">
 			ナビゲーションバー領域
 		</div>
 		<div data-role="content">
 			コンテンツ領域
 		</div>
 		<div data-role="footer">
 			フッタ
 		</div>
 	</div>
 </body>
 </html>

** 主なdata-role [#gdb886e0]

#html(<div style="padding-left:10px;">)
ナビゲーションバーやフッター、ボタンやリストなどにもそれぞれ data-roleが用意されており、追加したい箇所に
対象のdata-role属性をもつ要素を追加する事で簡単にそれっぽいページを作る事ができる。
|data-role|内容|h
|page|ページ全体用|
|header|ヘッダ領域用|
|content|コンテンツ領域用|
|navbar|ナビゲーションバー用|
|footer|フッター用|
|slider|フリップスイッチ(selectタグに指定するとフリップスイッチとして表示される)|
|button||
|controlgroup||
|fieldcontain||
|collapsible|開閉式コンテンツ|
|collapsible-set|アコーディオン式コンテンツ(開閉式コンテンツ)|
#html(</div>)

** その他の data属性 [#h9721b49]

#html(<div style="padding-left:10px;">)
また、data-role の他にも、体裁を整えたり、挙動を変える為の data-* 属性が用意されている。
|data-corners||
|data-icon|home or delete or plus or arrow-u or arrow-d or check or gear or grid or star or custom or arrow-r or arrow-l or minus or refresh or forward or back or alert or info or search|
|data-iconpos|left or right or top or bottom or notext|
|data-iconshadow|true or false|
|data-inline|true or false|
|data-shadow|true or false|
|data-theme|swatch letter (a-z)|
|data-type|horizontal or |
|data-id||
|data-position||
|data-title||
|data-inline||
|data-mini||
|data-shadow||
|data-theme||
|data-content-theme||
|data-ajax|true or false|
|data-dom-cache|true or false|
|data-prefetch|true or false|
|data-rel|slide or slideup or slidedown or pop or fade or flip|
#html(</div>)

** CSSクラス [#ecf0c3b0]

** jQuery Mobile によるHTML装飾 [#g5f9f926]
#html(<div style="padding-left:10px;">)
ui-grid 
#html(</div>)
jQuery Mobile が自動的に追加・変更する CSSセレクタや装飾後のHTMLを把握する事で、より細かなカスタマイズを行う事ができる。

** デザインのカスタマイズ方法 [#bae3e3de]
#html(<div style="padding-left:10px;">)
[data-role=header] { xxxx } などのように、data-role名をCSSセレクタとしてデザインをカスタマイズする事も可能だが、
jQuery Mobile が動的に追加・変更する CSSセレクタなどを把握する事で、より細かなカスタマイズを行う事ができる。
#html(</div>)
例えば、テキストボックスの場合は、以下のように自動装飾される。

#html(<div style="padding-left:20px">)
各領域には、以下のように自動的にclassなどが追加される。

*** data-role=header [#wa24ff7e]
素の記述
#mycode{{
&lt;div data-role="header" class="ui-header ui-bar-a" role="banner"&gt;
ヘッダ領域
&lt;/div&gt;
&lt;input type="text" id="text1" name="text1" value="" &gt;
}}

*** data-role=navbar [#te57761a]
jQueryMobileによる自動装飾後
#mycode{{
&lt;div data-role="navbar" class="ui-navbar ui-mini" role="navigation"&gt;
ナビゲーション領域
&lt;div class="ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow ui-body-c"&gt;
&lt;input type="text" id="text1" name="text1" value="" class="ui-input-text ui-body-c"&gt;
&lt;/div&gt;
}}
※その他の自動装飾の例は [[jQuery Mobileによる自動装飾後のHTML]] を参照。

*** data-role=content [#ca862f6f]
ここで、テキストボックスが無駄に多く取る余白(margin)を小さくしたい場合、
#mycode{{
&lt;div data-role="content" class="ui-content" role="main"&gt;
コンテンツ領域
&lt;/div&gt;
#text1 { margin : 0px !important; }
}}
などを記述しても、余白は小さくならない。
余白(margin)が設定されているのは、実際のテキストボックスではなく、.ui-input-text だから。

*** data-role=footer [#le16119a]
テキストボックスの余白を無くすには、以下のように記述する。
#mycode{{
&lt;div data-role="footer" class="ui-footer ui-bar-a" role="contentinfo"&gt;
フッター
&lt;/div&gt;
.ui-input-text { margin : 0px !important;}
}}

*** Aタグ [#yc4ce0c8]
特定のテキストボックスの余白だけ調整したい場合は、以下のようにdiv等で括って、
その配下の .ui-input-text に対して余白を指定する。など一手間かける必要がある。
#mycode{{
&lt;a href="test.html" class="ui-link"&gt;link1&lt;/a&gt;
}}
&lt;style&gt;
#text1_area .ui-input-text { margin : 0px !important;}
&lt;/style&gt;

*** input type="button" [#l86acaf7]
#mycode{{
&lt;div data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span"
      data-theme="c" data-disabled="false" class="ui-btn ui-btn-up-c ui-shadow ui-btn-corner-all" aria-disabled="false"&gt;
&lt;span class="ui-btn-inner"&gt;&lt;span class="ui-btn-text"&gt;button1&lt;/span>&lt;/span&gt;
&lt;input type="button" value="button1" class="ui-btn-hidden" data-disabled="false"&gt;
&lt;div id="text1_area"&gt;
&lt;input type="text" id="text1" name="text1" value="" &gt;
&lt;/div&gt;
}}

*** input type="text" [#a39ebd80]
#mycode{{
&lt;div class="ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow ui-body-c">
&lt;input type="text" name="text1" value="" class="ui-input-text ui-body-c"&gt;
&lt;/div&gt;
}}
このように、自動装飾後のHTMLがどうなっているかを把握しておかないと、余白調整すらままならない。

*** input type="submit" [#vf2817c0]
#mycode{{
&lt;div data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span"
     data-theme="c" data-disabled="false" class="ui-submit ui-btn ui-shadow ui-btn-corner-all ui-btn-up-c" aria-disabled="false"&gt;
&lt;span class="ui-btn-inner"&gt;&lt;span class="ui-btn-text"&gt;button1&lt;/span&gt;&lt;/span&gt;
&lt;input type="submit" value="button1" class="ui-btn-hidden" data-disabled="false"&gt;
&lt;/div&gt;
}}
◆解決方法
とはいえ、fieldset で括った場合や、data属性を足した場合など、全ての装飾結果を把握する事は困難。
そこで、google chrome を利用する。
chrome に表示されたページ上で対象の要素を右クリック→ [要素の検証] を選択すると、
素のHTMLではなく、javaScriptによる変更が反映された状態のHTMLが確認できる。

*** select [#a6dd7663]
#mycode{{
&lt;div class="ui-select"&gt;
    &lt;div data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-icon="arrow-d"
            data-iconpos="right" data-theme="c" class="ui-btn ui-shadow ui-btn-corner-all ui-btn-icon-right ui-btn-up-c"&gt;
        &lt;span class="ui-btn-inner"&gt;
            &lt;span class="ui-btn-text"&gt;&lt;span&gt;value1&lt;/span&gt;&lt;/span&gt;
            &lt;span class="ui-icon ui-icon-arrow-d ui-icon-shadow"&gt;&nbsp;&lt;/span&gt;
        &lt;/span&gt;
        &lt;select name="select1"&gt;
        &lt;option value="value1"&gt;value1&lt;/option&gt;
        &lt;option value="value2"&gt;value2&lt;/option&gt;
        &lt;/select&gt;
    &lt;/div&gt;
&lt;/div&gt;
}}

*** input type="checkbox" [#ea72ffac]
#mycode{{
&lt;div class="ui-checkbox"&gt;
    &lt;label for="checkbox1" data-corners="true" data-shadow="false" data-iconshadow="true" data-wrapperels="span"
                data-icon="checkbox-off" data-theme="c" data-mini="false"
                class="ui-checkbox-off ui-btn ui-btn-corner-all ui-fullsize ui-btn-icon-left ui-btn-up-c"&gt;
        &lt;span class="ui-btn-inner"&gt;
            &lt;span class="ui-btn-text"&gt;checkbox1&lt;/span&gt;
            &lt;span class="ui-icon ui-icon-checkbox-off ui-icon-shadow"&gt;&amp;nbsp;&lt;/span&gt;
        &lt;/span&gt;
    &lt;/label&gt;
    &lt;input type="checkbox" id="checkbox1" name="checkbox1" value="1"&gt;
&lt;/div&gt;
}}
※チェックボックスがON状態になった時は、data-icon=checkbox-onに、classが ui-checkbox-on、ui-icon-checkbox-on に変わる。

*** input type="radio" [#r5b7aeb5]

#html(</div>)


** イベント処理 [#d3fb87c1]
#html(<div style="padding-left:20px">)

*** 用意されているイベント [#mdd60218]

様々なイベントが用意されているが、とりあえず以下の3つさえおさえておけば大抵の事はできる。
様々なイベントが用意されているが、とりあえず以下をおさえておけば大抵の事はできる。
|イベント名|説明|補足|h
|pageinit|そのページが最初に読み込まれた時に実行されるイベント。||
|pageshow|ページを表示する際に実行されるイベント。|基本的にページ表示時には毎回実行されるが、data-ajax=falseなボタンで遷移した後に戻るで戻った場合等は実行されない。|
|pagebeforecreate|そのページがDOMツリーに組み込まれ、jQueryMobileによるHTML装飾が行われる前に起こるイベント。|このタイミングで動的にHTML要素を追加・編集すれば、jQueryMobileによるHTML装飾も行われる。|
|pageinit&br;pagecreate|そのページが最初に読み込まれた時に実行されるイベント。||
|pagebeforeshow|ページを表示する前に実行されるイベント。|基本的にページ表示時には毎回実行される。[戻る](data-rel=backなボタン)で戻った場合や、ダイアログを閉じてメインページに制御が戻った際にも実行される為、注意が必要。|
|pageshow|ページを表示する際に実行されるイベント。|~|
|pagehide|ページ遷移を行う時に、実行されるイベント。|data-ajax=falseのリンクやボタンをクリックした場合は実行されない。|
|pageremove|ページがDOMツリーから削除される時に起こるイベント。| DOMツリーに残しておきたいページ等は event.preventDefault() でremoveをキャンセルする事ができる。|

*** イベントの捕捉方法 [#ycfa2c4e]
data-ajax=falseでない限り、headタグ内に記述したJavaScriptは一度しか読み込まれないので、全ページで同じものを記述する。
ページ毎に異なる処理を記述する場合は、ページのidなどを指定するか、data-role=page 配下に処理を記述する。
ただし、data-role=page配下に記述する場合、onでなくbindを使用して記述する。(後述を参照)
%%ページ毎に異なる処理を記述する場合は、ページのidなどを指定するか、data-role=page 配下に処理を記述する。%%
%%ただし、data-role=page配下に記述する場合、onでなくbindを使用して記述する。(後述を参照)%%
ページ毎に異なる処理を記述する場合は、ページのidなどを指定してheadタグ内に記述する。
※data-role=page 配下にも書けるが初期化に限っては headタグ内の方が良さげ。(後述の注意点を参照。)
#mycode{{
&lt;head&gt;
&lt;script&gt;
$(document).on("pageshow", function(){
 // 全ページで行う初期表示処理
});
$(document).on("pageshow", "#page1", function(){
 // page1 のみで行う初期表示処理
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="page1" data-role="page"&gt;
&lt;script&gt;
$(document).bind("pagehide", "#page1", function(){
 // page1 のみで行うページ遷移前処理
});
&lt;/script&gt;
&lt;/div&gt;
&lt;/body&gt;
}}

*** イベントの捕捉時の注意点 [#ycfa2c4e]
headタグ内にイベント捕捉を記述した場合は、onによる捕捉でもbindによる捕捉でも
同一イベントに対する記述がある場合は、それら全てが実行される。
例えば、以下の例では 2回alertが表示される。
#mycode{{
&lt;head&gt;
&lt;script&gt;
$(document).on("pageshow", function(){
 alert("test1");
});
$(document).on("pageshow", function(){
 alert("test2");
});
&lt;/script&gt;
&lt;head&gt;
}}

data-role=page 配下にイベント捕捉を記述した場合、
bindによるイベント捕捉は上書きされるが、on によるイベント捕捉は上書きされずに追加される。
例えば以下の例では、このページを何度表示しても「bindによる捕捉」は一回しか表示されないが、
「onによる捕捉」はページにアクセスする度に表示回数が増えていく。
#mycode{{
&lt;div id="page1" data-role="page"&gt;
&lt;script&gt;
$(document).on("pageshow", "#page1", function(){
 alert("onによる捕捉");
});
$(document).bind("pageshow", "#page1", function(){
 alert("bindによる捕捉");
});
&lt;/script&gt;
&lt;div&gt;
}}

*** ボタン押下時のイベント [#l997b64e]
jQuery 1.7b1 以降は bind や live、delegate で書いていた所は全て on で書けるので(onが推奨らしい)
headタグ内で 対象ページのIDを指定して on でイベント捕捉するのが良いと思われる。
※jQuery 1.9 になると liveは無くなっているので、liveで書いていた所は全て on で記述するように変更する必要がある。
#mycode{{
&lt;head&gt;
&lt;script&gt;
$(document).on("pageshow", "#page1", function(){     // この書き方は live と等価
 // page1の初期処理
});
&lt;/script&gt;
&lt;head&gt;
}}


*** 動的に追加したHTMLに対して装飾を行う [#p8dc96f3]
動的に追加した要素は、jQueryMobileによるHTML装飾が行われない為、自分で装飾を指示する必要がある。
※ただし pagebeforecreate 時に追加した要素は装飾されるので、個別に装飾指示をしなくても良い。
#mycode{{
&lt;div id="#myDiv1"&gt;&lt;/div&gt;
&lt;script&gt;
$(document).on("pageshow", "#page1", function(){
    // 追加/変更した要素の親要素に対してcreateを実行する
    var btn = "&lt;input type=\"button\" value=\"動的に追加したボタン\" /&gt;";
    $("#myDiv1").html(btn).trigger("create");
    //$("#myDiv1").append(btn).trigger("create");
});
&lt;/script&gt;
}}

#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS