始めてのjqm


クラスメソッド 開発部
     ともだつばさ
このセッションの目的
誰が
 なんとなくjqmの事は分かったけど、もう少し知りた
 い人
何を
 実際にアプリを作るのに必要な話
どれくらい
 知らなかった事の分だけ
どうする
 知って持ち帰る

                             2
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             3
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             4
jqmの便利なところ
• タグ(アトリビュート)
  – モバイルに合わせたコンポーネントがそろっている
  – 使用するタグ自体はhtmlタグだが、data‐~を使って
    指定することでモバイル用の見た目にできる
• CSS
  – テーマ(スウォッチ)が5つ用意されている
  – 独自にテーマを作ることも可能
• スクリプト
  – ローカライズ
  – 戻るボタン自動表示
  – 他の前処理

                                   5
おさらい
• jqmでは、html5のdata‐~属性を使って、独自の機
  能を提供している
  (*この事実から必然的にjqmを利用するならhtml5
  宣言で書く必要がある)
• よく使われるのは
  data‐role、data‐theme、data‐icon、、、など
• 今回はアイコン/ボタン類とリスト表示にしぼって紹
  介します



                                        6
アイコンいろいろ
data‐iconで指定出来るアイコンは18個
矢印系:arrow‐l,arrow‐r,arrow‐u,arrow‐d,
演算子系:delete,plus,minus,
アクション系:check,gear,refresh,forword,back,
情報系:grid,star,alert,info,home,search

とりあえずアプリ作るのには十分そうな量がある




                                          7
ボタンいろいろ
data‐iconposでアイコンの位置を変えられる
・left,right,top,buttom,notext
・デフォルトはleft
・notextを指定した場合は
  アイコンだけ表示される
<a href="#" data‐role="button" data‐icon="check“
data‐iconpos="left">left</a>
<a href="#" data‐role="button" data‐icon="check“
data‐iconpos="right">right</a>
<a href="#" data‐role="button" data‐icon="check“
data‐iconpos="top">top</a>
<a href="#" data‐role="button" data‐icon="check“
data‐iconpos="bottom">bottom</a>
<a href="#" data‐role="button" data‐icon="check“
data‐iconpos="notext">notext</a>
                                                   8
ボタンいろいろ
ボタンは配置するだけだと画面の横幅いっぱいに表示
される。インラインボタンにすると適した大きさになる。
data‐inline=“true”を指定する

 <a href="#" data‐role="button" data‐icon="delete" data‐
 inline="true">close</a>
 <a href="#" data‐role="button" data‐icon="check" data‐
 inline="true">check</a>




                                                           9
ボタンいろいろ
data‐role=“controlgroup”でくくるとボタンがグループさ
れる
data‐type=“horizontal”で横並び出来る
 <div data‐role=“controlgroup”>
   <a href="index.html" data‐role="button">Yes</a>
   <a href="index.html" data‐role="button">No</a>
   <a href="index.html" data‐role="button">Maybe</a>
 </div>




                                                       10
リストいろいろ
ul,liなどの要素とdata‐role="listview"を用いる

 <ul data‐role=“listview” data‐theme=“g”>
   <li><a href="acura.html">Acura</a></li>
   <li><a href="audi.html">Audi</a></li>
   <li><a href="bmw.html">BMW</a></li>
 </ul>




                                             11
リストいろいろ
liの中に2つのa要素を持つとリストが分割される
data‐split‐iconで右側アイコンを変えられる
 <li><a href="sample4.html">Acura</a>
 <a href="">acura</a></li>




                                        12
リストいろいろ
data‐role=“list‐divider”を使う事でインデックスを表示
出来る
 <li data‐role="list‐divider">A</li>
 <li><a href="sample4.html">Acura</a>
 <a href="">acura</a></li>




                                         13
リストいろいろ
<span class=“ui‐li‐count”>{数}</span>でカウントバブ
ルを表示出来る
 <li data‐role="list‐divider">A</li>
 <li><a href="sample4.html">Acura<span class="ui‐li‐count">12</span>
 </a><a href="">acura</a></li>




                                                                       14
CSS(テーマ、スウォッチ)
• jqmではa~eまでの5つのテーマ(スウォッチ)が用意
  されていて、テーマを使うにはdata‐theme=“{a~e}”
  で指定する
• f~zに独自のテーマを割り当てる事が出来る
• ただし、設定出来る項目は膨大なので1から作るの
  は心が折れる...
  既存のa~eをベースにして作るか、「テーマロー
  ラー」を使う
 http://jquerymobile.com/themeroller/



                                        15
CSS(テーマ、スウォッチ)
cssの中を覗くと
/*Swatches*/
と始まるセクションの中
に各A~Eのテーマの定
義があるのでそれらを
コピペして新しいFを作
くればOK




                 16
CSS(テーマ、スウォッチ)
テーマローラーでは、
左ペインにあるインス
ペクタを使って各項目
の値を設定したり、右
ペイン上部にあるカ
ラーボックスを各UI要
素にドラッグアンドド
ロップして色を設定す
る事も出来る



                 17
スクリプトで一括設定
• ローカライズや共通設定は起動時に一括でやってし
  まう
• jqmが実行されると、document オブジェクトの
  mobileinit イベントが呼び出されるのでその中で処
  理をする
    $(document).bind(“mobileinit”, function(){
    // 初期値の上書き
    });
• htmlでのタグの順序は、次の通り
  <script src=“jquery.js”></script>
  <script src=“custom‐scripting.js”></script>
  <script src=“jquery‐mobile.js”></script>     18
スクリプトで一括設定
jquery本体の読み込みと   <script type="text/javascript" 
jqmの読み込みの間に右     src="http://code.jquery.com/jquery‐1.6.4.min.js"></script>
                 <script type="text/javascript">
記のスクリプトを走らせる       $(document).bind("mobileinit", function() {
                      $.mobile.loadingMessage
・ローディング中のメッ             = '読み込み中です;
セージ                   $.mobile.pageLoadErrorMessage
                        = '読み込みに失敗しました';
・読み込み失敗のメッ            $.mobile.dialog.prototype.options.closeBtnText
セージ                     = '閉じる';
・ダイアログの閉じるボタ          $.mobile.selectmenu.prototype.options.closeText
ンのラベル                   = '閉じる';
                      $.mobile.listview.prototype.options.filterPlaceholder
・セレクトメニューの閉じ            = '検索ワードを入力してください';
るボタンのラベル              $.mobile.page.prototype.options.backBtnText
・検索フィールドのプレイ            = '戻る';
スホルダー              });
                 </script>
・戻るボタンのラベル       <script type="text/javascript" 
の6つの設定が共通で可      src="http://code.jquery.com/mobile/1.0/jquery.mobile‐
能                1.0.min.js"></script>
                                                                              19
スクリプトで一括設定
「戻るボタン」を全画面で   <script type="text/javascript" 
出したい場合は、全ての    src="http://code.jquery.com/jquery‐
ページにアトリビュートを   1.6.4.min.js"></script>
               <script type="text/javascript">
付けていると面倒くさい
                 $(document).bind("mobileinit", function() {
ので、スクリプトで一括で        $.mobile.page.prototype.options.addBackBtn = 
設定をすると便利       true;
                 });
               </script>
               <script type="text/javascript" 
               src="http://code.jquery.com/mobile/1.0/jquery.mobile‐
               1.0.min.js"></script>




                                                                 20
スクリプトで一括設定
設定出来る項目は他にもい <script type="text/javascript" 
くつかある        src="http://code.jquery.com/jquery‐
                           1.6.4.min.js"></script>
                           <script type="text/javascript">
ajax制御には
                              $(document).bind("mobileinit", function() {
$.mobile.ajaxLinksEnabled
                                //viewportContentの設定
$.mobile.ajaxFormsEnabled       $.mobile.metaViewportContent = "width=device‐
あるが、非推奨                    width, minimum‐scale=1, maximum‐scale=1";
                                //ページトランジション
他の要素については                       $.mobile.defaultPageTransition = "slidedown";
http://dev.screw‐               //ダイアログ表示時のトランジション
axis.com/doc/jquery_mobile      $.mobile.defaultDialogTransition = "slidedown";
/api/configuring_defaults/      //ajax通信するか
                                $.mobile.ajaxEnabled = false;
を参照
                           });
                           </script>
                           <script type="text/javascript" 
                           src="http://code.jquery.com/mobile/1.0/jquery.mobile‐
                           1.0.min.js"></script>
                                                                             21
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             22
おさらい
• htmlの中に<div data‐content=“page”>として記述す
  れば、jqmのフレームワークが勝手にモバイル用に
  変換、表示してくれる
• 1つのhtmlの中にpageを複数作る事が出来る
• 遷移はid名を<a>のhrefに指定すれば良い




                                           23
pageを分ける
多くのjqm解説サイトだとコーディング例が1つのhtml
の中に複数のpageを作るように書いてあるけど、実際
どうするのが良いのだろうか?
• 状況によりhtmlを分ける:1つのhtmlの中にpageを
  何個も作っていたらサイズが大きくなる
• 次の様な例を考えてみる




     画面遷移
                ポップアップ

                                  24
pageを分ける
htmlをひとまず分けてみる
<script type="text/javascript">       元のhtml          <div data‐role="page" id="">              test1.html
$(function(){$("#popupBtn").click(function(){alert(     <div data‐role="header"><h2>test</h2></div>
“popupBtnが押された");});});</script>                        <div data‐role="content">
‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐                                <a href="./test2.html" data‐role="button" data‐
<div data‐role="page" id=“page1">                     transition="slide">test2</a>
   <div data‐role="header"><h2>test</h2></div>          </div>
   <div data‐role="content">                            <div data‐role="footer"><h4>test</h4></div>
      <a href=“#page2" data‐role="button" data‐       </div>
transition="slide">test2</a>
   </div>                                             <script type="text/javascript"> 
   <div data‐role="footer"><h4>test</h4></div>                                                  test2.html
                                                      $(function(){$("#popupBtn").click(function(){alert(“pop
</div>                                                upBtnが押された");});});</script>
<div data‐role="page" id=“page2">                     ‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐ ‐‐‐‐‐‐‐‐
   <div data‐role="header"><h2>test2</h2></div>       <div data‐role="page" id="">
   <div data‐role="content">                             <div data‐role="header"><h2>test2</h2></div>
      <p>test2</p>                                       <div data‐role="content">
      <a href="#" data‐role="button"                        <p>test2</p>
id=“popupBtn">popup</a>                                     <a href="#" data‐role="button" 
   </div>                                             id="testBtn">popip</a>
   <div data‐role="footer"><h4>test2</h4></div>          </div>
</div>                                                   <div data‐role="footer"><h4>test2</h4></div></div>
                                                                                                         25
pageを分ける
分けたものを実行するとどうなるのか
• 遷移後、ボタンを押下してもアラート窓が出ない
  どうも、スクリプトが動いていないらしい
 そこでブラウザのデバッグ機能を使ってコードの挙
 動を覗いてみる            もとのコードはそ
                         のまま




       test2.htmlのpage
       部分だけが挿入さ
       れる
                               26
pageを分ける
• <a>タグのhrefで他のhtmlのURLを指定した場合、
  jqmはajaxロードを行う
• その際にロード元htmlにロードされるのは、被ロード
  htmlのdata‐contet=“page”の部分だけ
• ヘッダ部分は読み込まれないので、当然そこに書い
  てあるスクリプトは、実際に使われていても読み込
  まれない
• 結果、スクリプトが動かない



                                  27
pageを分ける
ということで、選択肢は
  – 無理矢理スクリプトを読み込ませる様にする
  – ajaxロードを回避する
の2択

どちらを選択するかは、設計等々の条件による




                           28
pageを分ける
無理矢理スクリプトを読み込ませる様にする
data‐contet=“page”内のどこかにscriptタグを埋めれば
良い
(けど、、、美しくない)
   <div data‐role="page" id="">
     <script>
        $(function(){
           $("#testBtn").click(function(){
              alert(“textBtnが押された");
           });
        });
     </script>
     <div data‐role="header"><h2>header</h2></div>
     <div data‐role="content">
                                                     29
pageを分ける
ajaxロードを回避する
部分的にajaxさせたくない場合は
     link=“external”か、data‐ajax=“false”
を指定しておく
全体的にajaxさせたくない場合は
スクリプトのロード時に
    jQuery(document).bind("mobileinit",function()
    {jQuery.mobile.ajaxEnabled =false;});
を使う

                                                    30
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             31
事例を見てみる
• 「jQuery Mobile Gallery」
  (http://www.jqmgallery.com/)に山程事例があるの
  でこれを参考にしてみる
• ただし、その実装方法が良いかどうかはまた別の話
• β版とかα版もあるので注意する




                                          32
事例を見てみる
サイト                 特徴
Felt Bicycles       ・リスト表示を多用
                    ・jqmのコンポーネント/スキンをほぼそのまま利用
Stedesign           ・jqmの良いところを全て使いましたといった感じのサイト
                    ・1つのhtmlの中に複数のpageを定義している(おそらくほぼ全て)
Century 21          ・html内に複数のpageを定義するのと、外部htmlへリンクするの
                    とを使い分けている
Letters to Amanda   ・デザインが特徴的なサイト
15VISION            ・画面サイズに連動させて画面レイアウト変更
                    ・戻るボタンはあるけど、jqmの機能は使っていない




                                                      33
事例を見て分かること
pageはどう分けるか      ・静的なコンテンツだけであればhtml内に複数pageを定義する
                  のはあり(ただし、htmlのサイズを気にする必要はあり)
                 ・動的なコンテンツの場合は別のhtmlにせざるを得ない
                 ・ページを分ける場合にはjavascriptの処理に気をつける必要が
                  ある
jqm標準の部品はどうするか   ・テーマはカスタムしている事はあるが、積極的に利用している
                 ・意外に標準テーマそのままの場合も多い
                 ・UIが揃っている方が良いので、積極的に独自に実装する必要
                  はない(用意された部品を効果的に使うからこそF/Wの意味が
                  ある)
PCサイトとモバイルサイト    ・jqmの事例として上がっているサイトは、PC版とモバイル版は分
をどうするか            けていないサイトが多い
                 ・分ける必要がないならそのままでも
                 ・スクリーンサイズなどで見た目を変えている
「戻る」ボタン          ・戻るボタンは必ずしもやりたいことは実現できない
                 ・戻るボタンを表示していないサイトの方が多い
                 ・戻るボタンを表示する場合でも独自に実装している事が多い



                                                      34
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             35
jqmの不便なところ
冗長な記述          data‐themeをはじめ、どのタグでも同じ記述をするだろうと思
               われる部分でも、必要なタグ全てに記述を入れないといけな
               い事が多い。
いじろうと思うとそれなり   cssの量もかなりあるので、覚える/探すのが大変
に大変            テーマローラーを利用すれば覚えなくてもテーマが作成可能
               (使い勝手は微妙??)
               ThemeRoller for jQuery Mobile
               http://jquerymobile.com/themeroller/
不安定なヘッダフッタの ヘッダやフッタの固定や表示/非表示の機能、特にフッタの固
固定や表示/非表示機能 定は表示がチカチカして不安定に見える
            適する場面があれば便利
            次期バージョンでなんとかなるらしい
便利なような便利じゃな    戻るボタン
いような機能達        ajaxページ遷移
               固定ヘッダフッタ
重さ             もっさり感は否めない

                                                 36
jqmの便利なところ
開発は早く出来る      用意してくれている部品をうまいこと使って構築すれば、それ
              なりの早さで実装可能。あまり端末の個体差を考えないで良
              いのはやはりありがたい。
モックを作るには便利    早く作れるので、さっくりといくつかのモックを作って比較しな
              がらプロジェクトを進めるという事は出来る。
              それをそのままプロジェクトで使おうというマインドはやめた
              方が良い。(一般論として)
デザイナーとの協業には あくまでもhtmlなので、デザイナーとデベロッパーとが一つの
もってこい       ファイルを編集可能。(プログラマ寄りのF/Wでは難しい)
ユーザー(とユーザー予   jQueryのユーザーがそもそも多いのでそのままjQuery
備軍)の多さ        Mobileを使ってみようと思う人は多いはず(その結果良い進
              化を実現するという訳でもないけど)


まだまだ進化途中のフレームワークなので、欠点を把握しつつ、使える範囲で使ってい
くのが良さそう

                                           37
次期ver.でどうなるか
春までに、1.0.1(済)→1.1→1.2とバージョンアップ予定


1.0.1:公開済み    メンテナンスリリース
1.1:2月中旬/下旬   AMDサポート:Asynchronus Module Definition(非同期モ
予定            ジュール定義)
              実行時ダウンロードに対応→初期ロードが軽くなる
              TrueFixedToolbars:CSSベースで完全に固定された表示に
              Ajaxによるページ遷移をスムーズに素早くする
1.2:1.1の1ヶ月後く 新しいウィジェットの追加予定
らい(3月、4月)




                                                           38
今日のマイルストン
•   jqmの便利なところ
•   jqmはどんな仕組みなのか
•   jqmの事例をみてみる
•   jqmの課題とこれから
•   jqmとPhoneGapとを一緒に使ってみる




                             39
PhoneGapって?
• PhoneGapは、カナダのnitobi社が開発した、
  HTML+JavaScriptでiPhone/Androidなどのネイティブ
  アプリを開発する為のフレームワーク
• 2011/10にAdobe社により買収
• 最新バージョンは1.3.0(2012/01/31現在)
• jqmはPhoneGapをサポートしている




                                           40
環境の構築
• http://phonegap.com/からphonegapのSDKをダウン
  ロードする(最新は1.3.0ですが本セッションでは1.2.0
  を使用します)
• 本セッションではiOSアプリの開発を試してみる
• ダウンロードしたzipを解凍し、iOS>PhoneGap‐
  1.2.0.dmgをマウントする
• PhoneGap‐1.2.0.pkgを実行してインストール




                                           41
プロジェクトをつくる
•   Xcodeを立ち上げてFile>New>New Projectを選択
•   ダイアログでiOS>Applicationを選択
•   PhoneGap‐based Applicationのテンプレートを選択
•   プロジェクトに名前を付ける
•   (あとは道なりに)




                                           42
プロジェクトをつくる
             テンプレートの選択




             名前を付けると
             プロジェクトのできあがり

                     43
開発の準備
• これまでの操作でプロジェクトが出来上がっている
  はず
• プロジェクト外にwwwフォルダを作成して、そのフォ
  ルダ内にindex.html(と必要なファイル群)を配置
• 当該フォルダをプロジェクト内にドラッグアンドドロッ
  プしてリンクを作る




                                 44
開発の準備

            選択されているか
            確認する




フォルダをドラッグ
アンドドロップする




                       45
ファイルの配置
• 用意したindex.htmlに実装していく
• 外部スクリプトやhtmlは合理的に
• PhoneGapが用意しているAPIを使うには
  <script src=“./phonegap‐1.2.0.js”></script>
  をロードする必要あり
• 一度コンパイルを掛けると、該当ファイルがプロジェ
  クト下のwwwにコピーされる
• その時に、phonegap‐1.2.0.jsもコピーされる



                                                46
ファイルの配置



          コンパイルするとフォル
          ダの中身がコピーされ、
          PhoneGapのjsファイル
          も配置される




                       47
ホワイトリスト
• アプリ内から外部サイトへアクセスする場合はホワ
  イトリストでドメイン等を許可しておく必要がある
• アウトプットを確認してみて
  ERROR whitelist rejection
  があったら、次ページの様にPhoneGap.plistの
  ExternalHostsに許可すべきドメインを加える
• jsを外部から意図的にロードしていなくても、使って
  いるライブラリが外部通信する事もあるので注意す
  る必要がある


                                 48
ホワイトリスト

            ここに注意!!




ドメインを追加する

                  49
カメラロールから写真を取ってみる
• PhoneGapが用意しているAPIについては
  http://docs.phonegap.com/en/{各バージョン}
  /index.htmlに詳しくあります
• 写真データを取得するには
  navigator.camera.getPicture( cameraSuccess, 
  cameraError, [ cameraOptions ] );
  を利用する




                                                 50
パラメタ
cameraSuccess[Function]   データを取得出来た時のコールバック関数
cameraError[Function]     データの取得に失敗した時のコールバック関数
cameraOption[Object]      データ取得に関するオプション
                          quality:Number[0‐100]
                          destinationType:Number[0:DATA_URL,1:FILE_URI]
                          sourceType:
                          Number[0:PHOTOLIBRARY,1:CAMERA,2:SAVEDPHOTOA
                          Lbum]
                          allowEdit:Boolean
                          EncodingType:Number [0:JPEG,1:PNG]
                          targetWidth:Number
                          targetHeight:Number
                          MediaType:Number [0:PICTURE,1:VIDEO,2:ALLMEDIA]




                                                                            51
ソース
<body>                                      <script type="text/javascript" charset="utf‐8">
 <div data‐role="page">                     $(function(){
  <div data‐role="header">                   $("#selectPhotoBtn").click(function(){
   <h1>PhotoApp</h1>                            navigator.camera.getPicture(function(
  </div>                                           imageURI){
  <div data‐role="content">                     $("#selectedPhoto").attr("src", imageURI);
   <img id="selectedPhoto" width="600"        }, function(msg){
height="450">                                   alert("Error : " + msg);
  </div>                                      }, {
  <div data‐role="footer" class="ui‐bar"        quality:50,
data‐position="fixed">
   <div data‐role="navbar">                 destinationType:Camera.DestinationType.FILE_URI,
    <a href="#" 
id="selectPhotoBtn">Select Photo</a>        sourceType:Camera.PictureSourceType.SAVEDPHOT
   </div>                                   OALBUM
  </div>                                        });
 </div>                                      });
</body>                                     });
                                            </script>
                                 html                                                              js
                                                                                              52
実行結果
                  カメラロールに
                  入っている画像




ボタン押下

        画像選択のポップアップ

                      選択画像が表示される


                               53
まとめ
• HTMLとJavaScriptが分かっていればネイティブアプリ
  が作れるというのはうれしい
• ネイティブアプリと同じ操作感を出すのには苦労す
  る(というかムリ)
  ネイティブとは違う操作感になることを許容できるか
• 標準で用意されているプラグインでは足らず独自に
  プラグインを作らないとアプリ作りは難しい(逆に
  そっちの方のウェイトが大きいかも)
• デバッグが大変
• 既にweb版のアプリがあってそれに端末固有の機
  能を使いたいからネイティブアプリ化するというのは
  ありかも                              54
おわり




  ご静聴ありがとうございました。




                    55

Jqm20120210