ラベル jQuery_Mobile の投稿を表示しています。 すべての投稿を表示
ラベル jQuery_Mobile の投稿を表示しています。 すべての投稿を表示

2011年7月11日月曜日

[jQuery Mobile] headerに3つ以上のボタンを表示する

jQuery Mobileでは、header部にボタン要素を記述すると、1つ目は左寄せ、2つ目は右寄せ、と自動でレイアウトしてくれます。
しかし、ただ3つ以上ボタンを入れようとしてもレイアウトが崩れてしまいます。

sample1

これを回避して3つ以上のボタンを一列に並べる方法を2つ紹介します。

  1. controlgroupを使う

表示したいボタンをcontrolgroupとして、ひとつにまとめます。

<div data-role="header" data-backbtn="false" data-theme="b">
  <a href="#beforepage" data-rel="back" data-icon="arrow-l" data-direction="reverse" data-theme="a">Back</a>
    <h1>Header</h1>
    <div data-role="controlgroup" data-type="horizontal" class="ui-btn-right" style="top: 0px;">
    <a href="#hoge" data-role="button" data-icon="grid" data-iconpos="notext" data-inline="true">Relation List</a>
    <a href="#" data-role="button" data-icon="search" data-iconpos="notext" data-inline="true">Search</a>
  </div>
</div>

↓

sample2

このようにボタンを一列に並べることができます。しかし、controlgroupを指定したdivにstyle="top: 0px"を指定し忘れると、controlgroup要素が下寄せになってしまうので注意が必要です。

  1. divで囲う

上記の方法だと、右寄せにしたボタンがひとまとまりになってしまいます。 しかし、それぞれ個別のボタンとして表示したい、ということもあるでしょう。 その場合はただdivで囲えばOKです。

<div data-role="header" data-backbtn="false" data-theme="b">
  <a href="#beforepage" data-rel="back" data-icon="arrow-l" data-direction="reverse" data-theme="a">Back</a>
  <h1>Header</h1>
  <div class="ui-btn-right">
    <a href="#hoge" data-role="button" data-icon="grid" data-iconpos="notext" data-inline="true">Relation List</a>
    <a href="#" data-role="button" data-icon="search" data-iconpos="notext" data-inline="true">Search</a>
  </div>
</div>

↓

sample3

どちらの場合も、囲んだdivでひとまとまりと認識されるので、class="ui-btn-right"はdiv要素に記述してください。

2011年7月7日木曜日

[jQuery Mobile] input type="search"にキーボードイベントをバインドするには

jQuery Mobileで検索用入力エリアを作るには、

<input type="search">

を使います。これだけで、スマートフォンのネイティブアプリのようなスタイルを勝手に生成してくれます。

しかしこれだけだと、キーボードで入力しエンターキーを押しても検索を開始してくれません。
エンターキー押下時の処理が設定されていないからです。

ここで、エンターキー押下時の処理を追加するために下記のようなコードを書きます。
使用しているjQuery Mobileのバージョンは 1.0b1です。

<!-- html -->
<input type="search" id="searchinput">

/*--jQuery Mobile--*/
$("searchinput").keypress(function(e){
    if(e.keycode==13){
        //エンターキー押下時の処理
    }
}

はい。通常のjQueryではこれで動くのでしょうが、jQuery Mobileではこれだと動きません。
jquery.mobile-1.0b1.jsの3672行目あたりを見るとわかるのですが、type="search"の要素はページ生成時にjQuery Mobile側で動的にdiv要素で囲われています。
そして、原理はよくわかりません(知っている人教えてください)が、inputにイベントがバインドできなくなっているようです。
そのため、検索ボックスにイベントをバインドしたいときは、下記のように書きます。

$("div.ui-input-search").live("keypress", function(e){
    if(e.keycode == 13){
        //エンターキー押下時の処理
    }
}

動的に作成されるdivはui-input-searchクラスを持っているので、それを利用して指定しています。また、動的に生成されているdivですので、バインドにはlive()を利用する必要があります。

2011年6月22日水曜日

[jQuery Mobile] beta 1でハマった点まとめ

jQuery MobileのBeta 1 (jquery.mobile-1.0b1.js) が公開されましたね。
レスポンシブ・レイアウトへの対応やアドレスバーが隠れるようになったり、結構すごいです。
私も早速自分の作っているサイトに適応してみたのですが、幾つかつまずいた点があったのでまとめてみます。

・ページがスマートフォンに最適化されない。

なぜかデスクトップのブラウザと同じように表示されます。ちょっと悩みましたが、公式デモページのソースに答えはありました。一行追加するだけで解消です。

<meta name="viewport" content="width=device-width, initial-scale=1">

レスポンシブ・レイアウトに対応したことと関係あるんですかねー

・ clickイベントが使えない

デスクトップのブラウザでは普通に動作するのですが、Androidで試したところ、clickイベントにバインドしたファンクションが動いてくれませんでした。
これの答えは公式ブログに書いてありました。 KEY CHANGESの項に、

「アドレスバー隠すためにfastclickっていうイベント作ったよ。このイベントのせいでもしかしたらclickイベント使えなくなるかもねー(超意訳)」

とかそんなことが書いてあります。
回避策としては2つあります。

1. clickイベントではなくvclickイベントにバインドする。


2. mobileinitイベント時に、useFastClick(false)を設定する。


ちなみに、2番だとアドレスバーが隠れなくなるようです。vclickイベントにバインドを変更するのが無難かなー。

2011/09/06 補足: jQuery Mobile beta 2ではfastclickが廃止され、clickイベントに戻ったようです。一部端末でfastclickイベントか二度検出されたり、という不具合があったようです。

・vclickイベントからイベント発生元オブジェクトを取得する方法がわからない

これ個人的にすごくハマった。
alpha 4 では、動的にリストを作成し、各li要素にclickイベントをバインドして、 イベントからクリックされたli要素を取得、ということをやっていました。
この時、

$(event.currentTarget).children("#hoge").text();

という形でli要素内の任意の子要素を取得していました。
ところが、beta 1 でclickイベントをvclickイベントに変更すると、上の方法ではクリックされたliを取得できませんでした。
公式ブログやらjQuery Mobileのソースやらを読んでみると、vclickはマウスのクリックイベントとタッチパネルデバイスのタップイベントやらを統合していい感じに処理してくれるカスタムイベントのようです。
で、取得したイベントの中の要素をここを参考にしてこんな感じで全部見てみました。

var props = new Array();
for (var key in event){
    props.push(key);
}
props.sort();
$("#msg").html(props.join("<br />")).css("text-align", "left");

上記のコードを利用して、イベント内の怪しそうな要素をかたっぱしから見ていった結果、

$(event.originalEvent.target.parentElement).find("hoge").text();

でクリックされたli要素内の任意の子孫要素を取得できました。
なんかもっとスマートなやり方がありそうな気もするんですけどねー。 

・検索ボックスにイベントをバインドできない。 


別のエントリにまとめました。