画面遷移イベント

画面遷移イベント

pagebeforechange

画面遷移が呼び出される前に呼び出されるイベント

$(document).on("pagebeforechange",function(e, data){
   //イベント処理
});

dataは、
options
toPage属性をもつ

optionsは、画面遷移のオプション
toPageには、遷移先の画面のURL、もしくはDOMが入る

pagebeforeload

HTMLの読み込みがはじまる前に呼び出されるイベント
このイベント発生後、次の遷移する画面のDOMがAjaxにより読み込まれる

読み込まれるDOMは

<div data-role="page">

</div>

で指定された要素の中になる

jQueryMobileの場合、この中がページとして扱うため、ふつうのHTMLとは異なることに注意する

使い方は

$(document).on("pagebeforeload","#main",function(e, data){
     //イベント処理
});

dataにふくまれる情報はかなり多く
絶対URL
ホスト内のURL
遷移元画面のDOM
遷移先画面のDOM
などがふくまれる

pagebeforecreate

DOMのロード完了時に呼ばれるイベント
この状態のDOMは
jQueryMobileで画面部分が初期化される前なので
pagebeforecreateで追加されたDOMは
jQueryMobileのスタイルが適用される
このため、
jQueryMobileのスタイルを適用する静的なDOM追加に使うことになる

<div data-role="page" id="main">
<div data-role="content">
<div id="box"></div>
</div>
</div>

$(document).on("pagebeforecreate","#main",function(e,data){
$(#box).append("<button>ボタン追加</button>");
});

とすれば、

<div id="box"></div>

へボタンが追加される

pagecreate

pagebeforecreateイベントとほぼ同じ
違いは、beforeじゃないから
body要素へスタイルが適用された後になること
通常は
pagebeforecreateを使う

使い方は

$(document).on("pagecreate","#main",function(e){
   //イベント処理
});

pageinit

jQueryMobileでスタイルが適用された後に呼び出される
このタイミングでDOMはjQueryMobileにより変換される

注意点として、pageinitイベント以降に
DOMに要素を追加しても
jQueryMobileのスタイルが適用されないということ

つまり、pageinitイベントの中で要素を追加しても
jQueryMobileのボタンではなく
HTMLだけで作成したボタンになってしまう

$(document).on("pageinit","#main",function(e){
$("#box").append("<button>追加ボタン</button>");
});

これだと、ただのHTMLのボタンになる

このため、jQuerymobileのスタイルを適用するには
追加下要素へ対して
trigger(“create”)
を実行する

$(document).on("pageinit","#main",function(e){
$("#box").append("<button>追加ボタン</button>");
$(#box).trigger("create");

});

とする

pageinitイベント以後に要素を追加したときには
trigger(“create”)
を忘れないこと

また、
日付コンポーネント
jQueryMobile Validation
など、サードパーティーコンポーネントの初期化はここで行うことになる

画面遷移イベントの流れ

画面遷移イベントの流れ

画面を読み込んだ後なら
日付を表示するコンポーネント
入力値のチェックをするコンポーネントを動的に押し込む

画面を表示した後なら
ポップアップアニメーション開始、
位置情報取得開始

画面を非表示にする前や、画面遷移する前なら
アニメーション停止、
位置情報取得の終了など

流れとしては、画面遷移スタートで
pagebeforechangeイベント

DOMがロードされ
pagebeforecreate発生して
pagecreate

ウィジェット初期化してから
pageinit

そして
pageload

次に、pagebeforechange
ここまで元画面

pagebeforehideて元画面をかくして
pagebeforeshowで次画面表示

pageremoveで元画面のDOM削除

pagehideでかくして
pageshowで表示

pagechangeで画面切り替え

となる

画面遷移字に発生するイベントは大きく分けて3つ

すべての画面遷移で呼び出されるグローバルイベント
pagebeforechange
pagebeforeload
pageload
pagebeforechange
pagechange

遷移元の画面で発生するイベント
pagebeforehide
pageremove
pagehide

遷移先の画面で発生するイベント
pagebeforecreate
pagecreate
pageinit
pagebeforeshow
pageshow

となる

イベントが発生するフェーズに分けると

次のHTML画面の読み込みフェーズ
pagebeforeload
pagebeforecreate
pagecreate
pageinit
pageload

画面の遷移フェーズ
pagebeforechange
pagebeforehide
pagebeforeshow
pageremove
pagehide
pageshow
pagechange

の2つのフェーズになる

また
条件により実行されるイベントがある

次画面の読み込みフェーズは
画面かDOMにキャッシュされているとき実行されない

jQueryMobileによるWebアプリやサイトのトップページは必ずキャッシュされるため

pagebeforeload
pagebeforecreate
pagecreate
pageinit
pageload

は最初の1回のみ実行される

DOMにキャッシュする画面では
画面遷移時に
pageremove
は発生しない

ブラウザ標準イベントと仮想マウスイベントの違い

ブラウザ標準イベントと仮想マウスイベントの違い

反応は仮想マウスイベントのほうが速い

ブラウザ標準のmousemoveイベントだと
スクリーンにタッチした瞬間しかイベントが発生せず
スクリーンをなぞるようなイベントが取得できない

仮想マウスイベントのvmousemoveなら
スクリーンをなぞるようなイベントの取得が可能

ブラウザ標準の
click
mousedown
mouseup
だと連続してスクリーンをタップしたとき
前のイベントを取得するまでは次のイベントを取得できないので
イベントの取りこぼしが頻繁に続出する
つまり反応が悪い

仮想マウスイベントにすると、これより反応がよくなるので
イベントの取りこぼしが減る
なくなるわけではないので注意

このため、仮想マウスイベントのほうがレスポンスのよいアプリになる

仮想マウスイベント

仮想マウスイベント

jQueryMobileでは、タッチとマウスによるイベントを透過的に扱う仮想マウスイベントが使える

仮想マウスイベントは、
jQueryで使えるマウスイベントの
click
mousedown
mouseup
mousemove
mouseover
の先頭に
v
を付けたイベント名になる

以下は仮想マウスイベントのメモ

vclick
マウスクリック
もしくは
スクリーンタップ

vmousedown
マウスクリック
もしくは
スクリーンに触れたとき

vmouseup
マウスのボタンを離したとき
もしくは
スクリーンから指を離したとき

vmousemove
マウスが要素内に入ってきたとき
もしくは
スクリーンをタップしたまま指を動かしたとき
座標は現在タップしている位置になる

vmouseover
マウスが要素内に入ってきたとき
もしくは
スクリーンをタップしたまま指を動かしたとき
座標は最初にタップした位置になる

注意点としては、
vmousemove
vmouseover
の場合、スクリーンをタッチして上下に滑らすと
一緒に画面がスクロールし
期待した値が取得できない

このため、
preventDefaultを使い、
ブラウザのイベント伝播を防ぎ
ブラウザのスクロールを防ぐ必要がある

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

//ブラウザのデフォルト動作無効化
e.preventDefault;

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

});

となる

スクロール位置の検出

スクロールの開始と静止を検知するイベント

スクロールの開始を検知するscrollstartイベント
そして、スクロールの終了を検出するscrollstopイベント
の実装方法

例えば
一番上までスクロールしたら
1px下へスクロールさせ
ブラウザのnavigation bar を隠す

こうすると、画面が見やすくなる

$(window).on("scrollstop",function(e){

//スクロール位置が一番上のなったら
if(document.body.scrollTop== 0){

//縦方向へ1pxスクロールする
window.scrollTo(0,1);
}

});

このように、スクロール位置は
document.body.scrollTop
で取得できる

あと、Twitterみたいに、画面の一番下へ
スクロールしたら次のデータを読み込んで表示する
というように、一番下までスクロールしたことを検知するには

$(window).on("scrollstop",function(e){

//一番下までスクロールしたことを検知
if((document.body.scrollTop + window.innerHeight) == document.height){
//一番下までスクロールしたときの処理

}

});

となる

このように、
一番下までスクロールしたときの
スクロール位置である scrollTop

スクリーンの縦幅になる window.innerHeight
を足して
document.height
つまり、画面の縦幅と同じなら
一番下に達したと判断できる

端末の向き不向き検知するイベント

端末の向きを検知するorientationchangeイベント

jQueryMobileでは、端末の向きの変更を検知する
orientationchangeイベントが定義されていて
これを使うには

$(window).on('orientationchange',function(e){
orientation = e.orientation;
});

orientationの値は
縦から横向きになると landscape
縦なら portrait
になる

Androidアプリでも
縦はportrait
横向きなら landscape
になる

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

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

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

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");
});

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