jQuery MobileでiPhone対応のサンプルHTMLを作ってみた

jQuery MobileでiPhone対応のサンプルHTMLを作ってみた

気になっていたjQuery Mobileのα2が、jQuery 1.4.4と同時にリリースされたので、この機に試しに使ってみました。a-blog cmsとの組み合わせの実験も兼ねてますが、それは別エントリーで。


デモ用のURL

サンプルファイルのデモ

上記のURLにサンプルのデモを用意しました。Sencha Touchと違って、Firefoxでもそこそこ見れます。このブログにiPhone(ないしUAをそれに準じて偽装)からアクセスしても同様の表示がされます。

サンプルファイルのDL

サンプルファイルのダウンロード(zip)

このブログでは、CMSで動的にHTMLを出力していますが、サンプルファイルは、それらを普通のHTMLとして保存しました。良かったら中身を見て解剖してみてください。Webkit系を推奨。


2011-07-18追記:上記のサンプルファイルでは,jQuery Mobile alpha4.1が使用されていますが,同バージョンにはXSS脆弱性が確認されています。よって公開サイト用のベースとする場合は、かならず最新版のjQuery Mobileを利用するように差し替えてください


HTMLドリヴンで簡単に記述でき、Ajaxを使ったページングも自動化されている

jQuery Mobileをつかってみたら、こんな感じでした。戻るボタンが勝手に挿入されたり、各要素が自動で解釈されたり、その異様に自動化された解釈に払われているJSのコストが若干気になります。

  • HTMLドリヴンで、JavaScriptを1行もかかずに動作させられる
  • data-role属性で、要素の役割を指定するだけで、デザインと機能が適用される
  • CSSとJSを読み込んで、HTMLにclassやdata-*属性を記述するだけで大体の事はできる
  • リストなどのナビゲーションに、a要素が含まれていると自動でAjaxでページングする
  • モバイル版ライブラリとして、jQuery UI的なボタン表示やフォームパーツが充実している
  • 何かにつけてお節介なほどに自動で解釈しやがる

jQuery Mobileで指定されるHTMLの基本構造

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css"/>;
    <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>;
    <script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script>;
    <title>タイトル</title>
</head>
<body>
<div data-role="page">
    <div data-role="header">
          <p>へっだー</p>
    </div>

    <div data-role="content">
          <p>こんてんと</p>
    </div>

    <div data-role="footer">
          <p>ふったー</p>
    </div>
</div>
</body>
</html>

何はともあれ、Download | jQuery Mobileに載っているCopy-and-Paste Snippetをhead要素にコピペします。これでjQuery Mobileの動作に必要な、CSSとJSが揃います。

そしてHTMLを記述するわけですが、jQuery Mobileではdata-role属性でパーツの種類を指定すると、自動でデザインと機能が適用されます。data-role="page"の下には、それぞれheader, content, footerが並列で並びます。JSとCSSが色々なことを勝手に処理してくれるので、上記のソースをコピペするだけでもそれっぽい見た目が表示されるはずです。


ありがちな表現で使うクラスやdata-*指定などなど

jQuery Mobileは、適当にやっても大雑把に何とかなります。何とかなりすぎます。ここでは、細かい表現で、どうやるんだろう?ってなりがちなポイントだけ抑えてみます。

検索フィルターをつける

<ul data-filter="true" data-role="listview" role="listbox" data-theme="c">
      <li></li>
</ul>

リストにdata-filter="true"をつければ検索ボックスが、自動で挿入されます。

position:fixed的な表現にする

<div data-role="footer" data-position="fixed">
    <div data-role="navbar">
        <ul>
            <li><a href="./">トップ(新着)</a></li>
            <li><a href="./category.html">カテゴリー</a></li>
            <li><a href="./tag.html">タグ</a></li>
        </ul>
    </div>
</div>

Mobile Safariって、positon:fixedが効かないんですよね。jQuery Mobileでは、data-positionで指定できます。

フッターがダブらないようにする

<div data-role="footer" data-id="persistent">
    <div data-role="navbar">
        <ul>
            <li><a href="./">トップ(新着)</a></li>
        </ul>
    </div>
</div>

data-idで名前を指定して、一意なフッターであることを示せば、読み込んだときにダブりません。(つまり、指定しないと新しいページを読み込む度にフッターがダブります)

カウントバブルをつける

<ul data-role="listview" data-theme="c">
    <li><a href="#">a-blog cms</a><span class="ui-li-count">14</span>
</ul>

.ul-li-countでカウントバブルのスタイルが適用されます。

リストナビゲーションで、1アイテムを複数行にして説明を付与

<ul data-filter="true" data-role="listview" data-theme="c" data-inset="true">
    <li>
        <h2><a href="./article.html">CentOS(さくらのVPS)で、PHP5.3.3にアップデート</a></h2>
        <p><strong>サーバー</strong> /
            <time>2010-11-13</time>
        </p>
        <p>無名関数とか名前空間とか使いたいぞ 今日、パーフェクトPHP (PERFECT SERIES 3)
            を購入してみて、ぱらぱらとページをめくっていたら、急激にPHP5.3の機能を使ってコーディングしたくなりました。 PHP5.3.0へのRPMアップデート(CentOS5.3) | Yama's
            Memorandum ここを参考</p>
    </li>
</ul>

li要素の中に、pやimgが含まれていると、勝手に.ui-li-desc.ui-li-thumのクラスを割り当てて、サムネイルやディスクリプションとして、ナビゲーションのリスト表示に適用されます。実際に、リストの中に適当な要素を入れてみると、分かりやすいと思います。やりすぎー。

ボタンの右寄せとか左寄せとか

<div data-role="header">
    <h1>カテゴリー検索</h1>
    <a href="./search.html" data-icon="info" class="ui-btn-right">Find</a>
</div>

.ui-btn-rightとか.ui-btn-leftで、右や左に寄ります。ついでに、data-iconでボタンにつくアイコンの種類を変えられます。アイコンについて詳しくはこのあたりを参照。

テーマを指定する

<div data-role="page" data-theme="b">
     <!-- ぺーじ -->
</div>

data-themeで指定します。現時点(a2)では、a, b, c, d, eまでの指定に対応します。詳しくはここを参照。一括の指定が見当たらないので、ヘッダー、フッター、リスト、ボタンなどなど、各要素に対して個別でテーマを指定しないといけないようです。(よい方法あれば教えてくださいませー)

フォームの送信ボタン

<form action="http://havelog.ayumusato.com/"; method="post">
    <input type="search" name="keyword" value="" placeholder="検索語を入力"/>
    <input type="hidden" name="bid" value="2"/>
    <button type="submit" data-transition="fade">検索</button>
</form>

button要素でdata-transitionとかtype指定したりすると、submitできます。フォームパーツの表現はいろいろなものが用意されています。

jQuery Mobileによって操作されるURL

jQuery Mobileは、ajaxでページを読み込んだ状態のURLを下記のように補正して表現します。この状態でブラウザから静的なソースコードを表示すると、一番最初に表示したページのHTMLが表示されます。

#本来のURL
http://example.com/subdir/category.html
 ↓
#本来のURLをjQuery Mobileがajaxで読み込んだ際のurl
http://example.com/subdir/#category.html

パスを#以後に保持します。戻るボタンの処理だとか、静的なURLの兼ね合いだとか色々ありそうですが、詳細は割愛。

例えば、http://jquerymobile.com/demos/1.0a2/#docs/toolbars/docs-navbar.htmlが表示されているときに、本来のページの静的なソースコードを確認する際には、http://jquerymobile.com/demos/1.0a2/docs/toolbars/docs-navbar.htmlにアクセスします。

この点に気づかないと、公式のサンプルやデモを確認する際に、うまく初期状態のHTMLを参照できなくて不便です。FirebugやInspectorで確認しても、どこからどこまでがJavaScriptによって操作された結果なのか分かりづらいです。

最後につかってみた感想

まだまだアルファ版だけに動作が不安定です。使い方が簡単すぎるだけに、手元の実装が間違ってるというよりもライブラリ本体の問題のように思います。

とはいえ、使い方が簡単すぎる点が、正式版に向けて大いに期待できます。適切に実装されたSencha Touchと比べると、レスポンスがもっさりしている印象ですが、HTMLドリヴンな簡便性で、これだけの表現を引き出せるのは貴重です。

ケースバイケースで使い分けていきたいところですね。

参考サイト

公式のドキュメントとデモが一番の聖典です。