jQueryでタップやスワイプなどのスマートフォン操作を取得する+イメージスライダーのサンプル
スマートフォンでも使えるスライダーを作りましたので宜しければどうぞー
タップ、スワイプ、指を離すという動作を取得する
jQueryにはスマートフォンのタップなどを取得するタッチイベントというものが有ります。ところでタップとタッチってどちらが正しいのでしょうか…よく迷います。
touchstart : タップしたときに発生
touchmove : スワイプしたときに発生
touchend : タップした指を離した時に発生
サンプルはiPhoneやAndroid等、タッチパネル搭載端末でご覧下さい。全ソース見たい方はこちらから
jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | jQuery(document).ready( function (){ /* * タップ、スワイプ、指を離した時のイベントハンドラ */ $( "#touch" ).bind( "touchstart" , TouchStart); $( "#touch" ).bind( "touchmove" , TouchMove); $( "#touch" ).bind( "touchend" , TouchLeave); /* * タップした位置をメモリーする */ function TouchStart( event ) { $( "#event" ).html( 'タップしました' ); var pos = Position(event); $( "#touch" ).data( "memory" ,pos.x); } /* * スワイプ * タップした位置からプラスかマイナスかで左右移動を判断 */ function TouchMove( event ) { var pos = Position(event); //X,Yを得る if ( pos.x < $( "#touch" ).data( "memory" ) ){ $( "#event" ).html( '左に移動' ); } else { $( "#event" ).html( '右に移動' ); } $( "#leave" ).html( '移動距離 X=' +pos.x+ ' , Y=' +pos.y); } /* * 指を離す */ function TouchLeave( event ) { $( "#event" ).html( '指を離しました' ); } /* * 現在位置を得る */ function Position(e){ var x = e.originalEvent.touches[0].pageX; var y = e.originalEvent.touches[0].pageY; x = Math.floor(x); y = Math.floor(y); var pos = { 'x' :x , 'y' :y}; return pos; } }); |
それぞれのタッチイベントごとにイベントハンドラを用意し、どんな操作をしたか表示する単純なものです。スワイプは左右どちらにスワイプしたかを判断させています。処理としては、タップしたときの位置をメモリーしておき、スワイプした位置と比較して判断します。メモリーはjQuery.data()を使っています。
1 | < div id = "touch" data-memory = '' >タップ</ div > |
これを踏まえてイメージスライダーを作ってみる
左右にスワイプした事を取得出来るのですから、指でスライドさせるイメージスライダーがぱっと浮かぶかなぁと思いますので、これを作ってみます。
サンプルはiPhoneやAndroid等、タッチパネル搭載端末でご覧下さい。全ソース見たい方はこちらから
画像部分
1 2 3 4 5 6 7 8 9 10 11 | < div id = "images" data-memory = '' data-now = '' > < div id = "swipe" > < ul > < li >< img src = "img/01.jpg" id = "1" /></ li > < li >< img src = "img/02.jpg" id = "2" /></ li > < li >< img src = "img/03.jpg" id = "3" /></ li > < li >< img src = "img/04.jpg" id = "4" /></ li > < li >< img src = "img/05.jpg" id = "5" /></ li > </ ul > </ div > </ div > |
画像をLIで並べ、それぞれIDを1~振ります。
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #images { width : 200px ; margin-right : auto ; margin-left : auto ; overflow : hidden ; height : 145px ; position : relative ; } #images ul li{ list-style : none ; width : 200px ; position : absolute ; } #swipe{ position : absolute ; } |
画像は絶対位置を指定して横に並ぶようにし、一枚だけ表示するようにします。ですので、#swipeの左から(left:xxx)の距離を変更する事で、画像をスライドさせる事になります。
jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | jQuery(document).ready( function (){ $( "#images" ).data( "memory" ,1); //デフォルト 1枚目 $( "#swipe" ).bind( "touchstart" , TouchStart); $( "#swipe img" ).bind( "touchmove" , TouchMove); $( '#images' ).after( '<div id="img_page"></div>' ); //ページャー要素を下に追加 /* * 画像枚数に応じてpostionを設定 * 幅が200なので、<li style="left:200(400,600...)">画像</li> のような感じで進む */ var i=0; $( "#swipe ul li" ).each( function (){ var pos = i*$( "#swipe li" ).width(); $( this ).css({ "left" :pos}); var p = i+1; $( "#img_page" ).append( '<span id="imgp' +p+ '">●</span>' ); //枚数分だけ●を表示 i++; }); $( "#imgp1" ).css({ "color" : "#999999" }); //一つ目の●の色を濃くする /* * タップ */ function TouchStart( event ) { var pos = Position(event); $( "#images" ).data( "now" ,pos.x); //タッチした位置を記録 } /* * スワイプ * タップした位置からプラスかマイナスかで左右移動を判断 */ function TouchMove( event ) { var pos = Position(event); // X,Yを得る var move = null ; // 左右初期化 var id = $( this ).attr( 'id' )|0; // 画像ID *数値としておく |0 var len = $( "#swipe img" ).length; // 画像枚数 /* * 移動幅 (次の画像にスライドする幅) * 1枚め→2枚めの場合は 1*200で、#swipesのスタイルをleft:-200にする事で2枚めに移動する事になる */ var li_w = $( "#swipe li" ).width() * id; //左右どちらにスワイプしたか *タップした位置と比較。 if ( pos.x < $( "#images" ).data( "now" ) ){ move = 'left' ; } else { move = 'right' ; } switch (move){ case 'left' : //全枚数(5枚)目以外なら処理 if (id != len){ $( "#swipe" ).animate({left:-li_w}, 500, function (){ //↑で計算した 次の画像に移る際の#swipeの左からの距離をアニメートで徐々に変化させる $( this ).queue([]); $( this ).stop(); }); //●をいったん初期化して[次]の●色を変更 clear_pager(len); var nxt = id+1; $( "#imgp" +nxt).css({ "color" : "#999999" }); } break ; case 'right' : //1枚目以外なら処理 if (id != 1){ li_w = li_w - ( $( "#swipe li" ).width()*2 ); //前の画像は少し特殊で、計算した移動距離から幅の2倍を引いた値とする $( "#swipe" ).animate({left:-li_w}, 500, function (){ $( this ).queue([]); $( this ).stop(); }); //●をいったん初期化して[前]の●色を変更 clear_pager(len); var nxt = id-1; $( "#imgp" +nxt).css({ "color" : "#999999" }); } break ; } } /* * ページャーの●の色を初期化 */ function clear_pager(len){ for ( var i=1; i<=len; i++){ $( "#imgp" +i).css({ "color" : "#DDDDDD" }); } } /* * 現在位置を得る */ function Position(e){ var x = e.originalEvent.touches[0].pageX; var y = e.originalEvent.touches[0].pageY; x = Math.floor(x); y = Math.floor(y); var pos = { 'x' :x , 'y' :y}; return pos; } }); |
ごちゃーっとしてますが、#swipeの位置を変更しているだけです。但し、これはタッチイベントを使って何が出来るかってサンプルです。スマフォ&PC対応の画像スライダープラグインが有りますので、実用的にはそちらを使う方が良いと思います。
左右どちらにスワイプしたかって事を判断出来るって事は、もちろん上下も判断出来ます。ということは、上下左右のコントローラーが作れるってことなので、簡単な迷路ゲームとか作れそうですね。