スマホのタッチイベントについて

スマホのタッチイベントについて

タッチイベントの種類のメモ

tap
マウスをクリック、もしくは
タッチスクリーンをタップしたたときに発生する
これはvclickと基本的に同じ

taphold
クリックしてボタンを押しっぱなし
もしくは
タップして長押しすると発生

swipe
素早く指を滑らすか
もしくは
クリックして素早くマウスを動かすと発生

swipeleft
素早く指を左に滑らすか
もしくは
クリックして素早くマウスを動かすと発生

swiperight
素早く指を右に滑らすか
もしくは
クリックして素早くマウスを動かすと発生

tapの
よくある使い方は
手書きアプリとか、お絵かきアプリ

書き方としてはまず領域を
divとか
canvas
て決める

とりあえず、今回はdiv

<div id="box" style="width:300px; height:300px;"></div>

次に、Javascriptで座標を取得する

$(document).on("tap","#box",function(e){

//座標取得
x = e.pageX;
y = e.pageY;

});

tapイベントのみ、イベントが発生した座標取得ができる

また、PCブラウザなど
マウスデバイスの操作でもタッチイベントの取得が可能

jQuerymobileの問題対処

問題対処のための自分なりのルールを作っておくとバグが減る

なお、ルールは書籍やサイトなどを参考に後々変更していく予定

対処ルールその1

画面遷移を利用するとき、別の画面に同じidがあってもイベントが設定されないようにする

このためには、以下のような書き方をする

$(document).on("pageinit","#text",function(e){
$(this).on("click","#btn",function(e){
alert("hello");
});
});

この書き方をする理由は
pageinitイベントの中でイベント定義することで
画面に対するイベントをまとめて定義できるから

これは、ある画面に対するイベント定義を書いた場所が分散すると、コードがわかりにくくなるから

また、thisによるデリゲードを使うことで
この画面にイベントを追加しているのがわかりやすくなる

ちなみに、デリゲードとは
要素の子要素の中のセレクタにマッチする要素にイベントを追加すること

対処ルールその2

ready()を使わない

jQueryMobileを使うときに
ready()は、基本的に最初に画面を読み込んだときしか実行されない

このため、ready()ではなく pageinitイベントを使うことで初期化処理を書く

対処ルール3

すべてのイベント定義は1つのJavascriptファイルへまとめる
理由は、jQueryMobileは
2画面目以降のhead要素内のscript要素を実行しないから

このため、最初の画面で、全画面分のイベント定義をしておく

これをevent.jsとか
custom.jsとかにして読み込んでおく

jQueryMobileの注意点

jQueryMobileのイベント定義の注意点

2ページ以降はhead要素のscriptが実行されない
これは、jQueryMobileは、2画面目以降のDOMは
AjaxでHTMLを取得し
画面をレンダリングしている
このとき、data-role=”page”で定義された要素以外は無視するため
2画面目以降のhead要素は読み込まれない

このため、1画面目に読み込ませるページで
Javascriptを読み込ませる

jQueryMobileでは、

<div data-role="page">

</div>

の間で管理しているので
普通のHTMLと同じように考えると
表示されないことがあるので注意

次の注意点として、セレクタで指定したイベントが、複数のページで動作することがあるということ
これは、data-role=”page”ごとで管理しているけど
id とかクラスが同じところがあると
識別がされず実行されてしまう
対策としては、被らないようにユニークなもので id=”” class=”” の中身を指定すること

そして、イベントの書き方がたくさんありすぎること
自由なのはいいけど、自由すぎてバグになりやすい

例えば、ボタンを押したらhelloと表示することさえ5つのやり方がある

その1

$(document).on("pageinit","#text",function(e){
$(this).on("click","#btn",function(e){
alert("hello");
});
});

その2

$(document).on("pageinit","#text",function(e){
$(e.target).on("click","#btn",function(e){
alert("hello");
});
});

その3

$(document).on("pageinit","#text",function(e){
$("#text #btn").on("click",function(e){
alert("hello");
});
});

その4

$(document).on("pageinit","#text",function(e){
$("#text").on("click","#btn",function(e){
alert("hello");
});
});

その5

$(document).on("click","#text #btn",function(e){
alert("hello");
});

このように、いくつかやり方はあるため
自分なりのルールを決めておくとわかりやすいしバグの防止にもなる

イベント追加と削除

jQueryMobileのイベント処理

$(#mybutton).on("click",function(e){
alert("スイッチオン!");
});

これだと
イベントを追加する要素の読み込み完了後でないと
イベント追加ができない

このため、追加したいイベントの前に
イベント追加scriptを書くと
正しく動作しない

このため、イベント追加したい要素の後へscriptを書くことになる

これが静的、つまりあらかじめ書いておくやり方

次に、動的、つまりプログラミングによる制御でイベント追加するやり方

これは、最初はHTMLに書かれてなくて
後から表示されるときに追加される

Twitter、Facebook、メール閲覧ソフトなどは
情報の更新で新しい情報表示しているのは
後から要素を追加している

あと、ほとんどの場合
JavascriptはHTMLのbodyの中じゃなくて
headの中へ書いている

こういった場合のイベント追加には

Javascriptの構文で

$(document).on(イベント名, セレクタ, ハンドラ)

となる
イベント名は、clickとかで
セレクタは対象のid
ハンドラは行う処理

例えば

<button id="save">保存</button>

このボタンへイベント追加するなら

$(document).on("click",""save",function(e){
   //保存する処理
});

とする

この追加したイベントを削除するには
off()を使う

通常は、Webアプリならイベントを削除はやらない

これは、画面遷移すると、すべてのイベントがクリアされるから

しかし、jQueryMobileだと
デフォルト動作で最初に読み込まれた画面がAjaxで次々と別画面を読み込んで画面を切り替え表示してしまう

つまり
通常のwebアプリとは違い
jQueryMobileの場合は
イベントを削除しない限りずっと残る

ボタンやテキストボックスなどのイベントは
コンポーネント固有なのであまり影響ないけど
スクロールイベントとか
各種センサー、位置情報などは
必要のない画面へ遷移しても処理し続け
思わぬ動作をすることがある

このため、一度追加したイベントは
off()で削除する

構文は

$(window).off("イベント名")

イベントの削除は
画面遷移して、今の画面を離れるときに使うことが多い

$(document).on("追加したいイベント","追加対象のid",function(e){
$(window).off("削除するイベント");
});

日付入力UI変更

日付入力UI変更

スロット画面みたいな日付入力以外にも
カレンダーから入力する方法もある

予約サイトとかだと
この方がわかりやすい

日付入力方法を変えるには
data-options=””
でmodeを指定する

data-role=”fieldcontain”
でjQueryMobileのフォーム作成

<div data-role="fieldcontain">
<label for="date">カレンダー</label>
<input type="date" name="date" id="date" data-role="datebox" data-options='
{"mode":"callbox",
"dateFormat","YYYY/MM/DD"}'/>
</div>

となる

グリッドレイアウト

グリッドレイアウトの利用

jQueryMobileでは、グリッドレイアウト支援機能がある

グリッドレイアウトは
均等な長さで部品を並べるときに使える
グリッドレイアウトを使うには

class=”ui-grid-a”
というように
カラム数を指定して
並べたい要素へ
class=”ui-block-a”というように指定する

ちなみに、
ui-gridで指定できるのは a~dになる
aが2
dが5
というようにカラム数を指定する

並べたい要素へ指定する
ui-block は、カラム数+1なので
ui-grid-d
なら
使えるui-blockは
ui-block-e
までになる

もし、
グリッドレイアウトで
ボタンを2つ並べたいのなら

<div class="ui-grid-a">

<div class="ui-block-a">
<button>保存</button>
</div>

<div class="ui-block-b">
<button>キャンセル</button>
</div>

</div>

となる

もし、ボタンを3つ並べて表示するなら

<div class="ui-grid-b">

<div class="ui-block-a">
<button>ホーム</button>
</div>

<div class="ui-grid-b">
<button>お気に入り</button>
</div>

<div class="ui-grid-c">
<button>検索</button>
</div>

</div>

となる

さらに、複数行にして
テレビのリモコンみたいにするなら
子要素の
class=”ui-block”を繰り返すことで簡単にできる

[/html]
このように、
class=”ui-block-a”
から
class=”ui-block-c”
の繰り返しを3回することで
3×3のマスになるように配置している

ただ、グリッドレイアウトに関しては導入するなら
jQueryMobileよりも
Bootstrapのほうが楽かもしれない

リストの動的変更

リストの動的変更

リスト要素を動的に追加、つまりプログラムでコントロールするなら
listview(“refresh”)
を使ってリストを更新すること

理由は、通常の要素追加だけだと
jQueryMobileのスタイルが追加されないため

なので、jQueryMobileを適用するには
通常の要素追加のあとに
listview(“refresh”)
を仕掛けることになる

これほ、マッシュアップで使うことになる
あとは、API関連とか

&lt;div data-role=&quot;page&quot; id=&quot;listview-add&quot;&gt;
&lt;div data-role=&quot;container&quot;&gt;
&lt;h1&gt;要素を動的に追加&lt;/h1&gt;
&lt;form&gt;
&lt;ol data-role=&quot;listview&quot; data-inset=&quot;true&quot; id=addlist&quot;&quot;&gt;
&lt;li&gt;要素1&lt;/li&gt;
&lt;li&gt;要素2&lt;/li&gt;
&lt;li&gt;要素3&lt;/li&gt;
&lt;/ol&gt;
&lt;/form&gt;
&lt;button id=&quot;addbtn&quot;&gt;要素を追加&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
//リストの要素を動的に追加
$(document).on(&quot;pageinit&quot;,&quot;#listview-add&quot;,function(e){

$(this).on(&quot;click&quot;,&quot;#addbtn&quot;,function(e){
var target b= $(&quot;#addlist&quot;);
target.append(&quot;&lt;li&gt;追加要素&lt;/li&gt;&quot;);
target.listview(&quot;refresh&quot;);
});

});

これで、要素追加のボタンである
#addbtnをタップすると
append()により
li要素の一番下へ要素が追加される
追加されるのは

<li>追加要素</li>

になる

また、通常のHTMLならこれでokだけど
jQueryMobileではデザインを適用するには
今回のように
listviewに対して refreshをかける

refreshし忘れると、ただのHTMLになってしまうので注意

コンテンツの折りたたみ

コンテンツの折りたたみ

jQueryMobileでは
collapsibleを使うことで
簡単に折りたたみ可能なコンテンツを作成できる

モバイル版Wikipediaみたいなかんじ
ソースでは
data-role=”collapsible”
で指定する

<div data-role="collapsible">
<h3>見出し</h3>
<p>本文</p>
</div>

これだけで、簡単にタップすると
展開、折りたたみの動作をするコンテンツが作成できる

これだと、最初は閉じた状態になるけど
最初から展開状態にしたいのなら
data-collapsed=”false”
を指定する

今回の場合なら

<div data-role="collapsible" data-collapsed="false">
<h3>見出し</h3>
<p>本文</p>
</div>

また、折りたたみ可能なコンテンツと組み合わせて、アコーディオンが作れる
Wikipediaがそのいい例

では、ソース
今回のは最初から開いているのと
閉じているのを組み合わせている

途中の
data-role=”collapsible”
で折りたたみ可能にして

data-collapsed=”false”
で開いた状態にしている

<div data-role="collapsible-set"
<div data-role="collapsible" data-collapsed="false">
<h3>見出し</h3>
<p>本文、ここは最初から表示される</p>
</div>

<div data-role="collapsible">
<h3>見出し その2</h3>
<p>本文、最初は見えないよ</p>
</div>

<div data-role="collapsible">
<h3>見出し その3</h3>
<p>本文、これも最初は見えないよ</h3>
</div>

</div>