IPhoneでtouchstartイベントとtouchendイベントを遊んでいます。 divを含むサンプルページを作成しました。これをタッチしてページをスクロールすると、開始位置と終了位置のy座標が返されます。
リンク: http://jsbin.com/ibemom/2
jQuery:
var touchStartPos;
$('.theDiv')
.bind('touchstart', function(e){
touchStartPos = e.pageY;
})
.bind('touchend', function(e){
alert(touchStartPos + ' | ' + e.pageY)
})
ただし、iPhoneでそのページをロードすると、アラートは両方の値をゼロとして報告し続けます。誰かが私が持っているもので何か間違っていると思いますか?
更新:
JQuery Mobileプロジェクトで次のコードを見つけました: https://github.com/jquery/jquery-mobile/issues/734
それからのコメントそれは立ち往生しました:
// (in iOS event.pageX and event.pageY are always 0 )
なぜなのかはわかりませんが、少なくとも同じことを知っている誰かを見つけました。そのページのサンプルコードを調べて、解決策があるかどうかを確認します。
アップデートII:
さて、上のリンクのサンプルコードを確認すると、次のように実際の値が返されます。
e.originalEvent.touches[0].pageY
キャッチは、私は今それが私が必要とするものではないことを理解しています。これは、ブラウザーウィンドウではなく、イベントをHTMLドキュメントに関連してアタッチしたオブジェクト内でタッチした領域のYオフセットを返します。
私の目標は、画面のどこでタッチが開始し、どこで終了したかを把握して、その値を比較することです。それらがかなり異なる場合は、タッチではなくスワイプが実行されたと見なします。
アップデートIII:
これらの例への参照も見つけています。
e.originalEvent.touches[0].pageX
event.targetTouches[0].pageY
私もそれらを動作させるようには見えませんが。どちらも未定義のエラーを返します。
アップデートIV:
1つの解決策は、ドキュメント自体のoffset()を追跡することです。ドキュメントにtouchendイベントを適用し、オフセットを確認できます。
これの問題は、私のtouchendイベントが最初に私のページの要素でトリガーされ、それからドキュメント(バブリング)で発生することです。そのため、オブジェクトのtouchendイベントで何をすべきかを理解する必要がある前に、それがタッチであったかスワイプであったかを実際に判断することはできません。
まだこれを考えています...
簡単に言えば、指が画面から離れたときにタッチを検出できないということです(touchend
)。
私の最初の例はそれを証明します: http://jsfiddle.net/Y4fHD/
次に、回避策について説明します。またはそれをあなたが望むものと呼びます。タッチが終了したため、touchend
イベントを検出しないのは意味があるかもしれません。
ハンドラーをtouchmove
イベントにバインドします。 http://jsfiddle.net/Y4fHD/1/
var endCoords = {};
$(document.body).bind("touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
そして、変数endCoords
を使用して、最後のタッチを判別します
$(document.body).bind("touchend", function(event) {
$('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});
デバイスをタップしてみてください。その後、エラーは引き続き発生します:なぜですか?あなたは自分のタッチを動かしていないからです。
touchstart
の準備がすべて整っていれば、endCoords
変数が定義されます: http://jsfiddle.net/Y4fHD/2/
var endCoords = {};
$(document.body).bind("touchstart touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
そして、変数endCoords
を使用して、最後のタッチを判別します
$(document.body).bind("touchend", function(event) {
$('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});
次に、デバイスをタップしてみてください!
いくつかの最後の注意事項は次のとおりです:Make to variables:startCoords
and endCoords
then use these in the touchend
event: http://jsfiddle.net/Y4fHD/ 3 /
var startCoords = {}, endCoords = {};
$(document.body).bind("touchstart", function(event) {
startCoords = endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchmove", function(event) {
endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchend", function(event) {
$('p').text("Your touch on the axis: " + Math.abs(startCoords.pageX-endCoords.pageX) + "x, " + Math.abs(startCoords.pageY-endCoords.pageY) + "y");
});
注意:
上記の例はどれもテストされていません。うまくいくことを願っています!Math.abs
は、数値の絶対値を示します。例:-5は5になります
上記のNULLの答えは、touchstart-bound関数でstartCoordsをendCoordsに割り当てることができないことを除いて、私にとってはうまくいきました。次に、同じオブジェクトをポイントし、endCoordsが更新されるとstartCoordsも更新されるようにします。 touchendイベントが発生すると、startCoordsは常にendCoordsと等しくなります。
以下のコードを更新しました。これは、iOS 6.0のSafariを使用するiPad 3で私にとってはうまくいきました。数式を修正してエラーを表示し、touchend-bound関数内のMath.abs()を削除するためにも編集されました。また、touchmove-bound関数内にevent.preventDefault()呼び出しを追加して、これらがiOSでもGoogle Chrome=で機能するようにしました。
var startCoords = {}, endCoords = {};
$(document.body).bind("touchstart", function(event) {
endCoords = event.originalEvent.targetTouches[0];
startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
});
$(document.body).bind("touchmove", function(event) {
event.preventDefault();
endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchend", function(event) {
$('p').text("Your touch on the axis: " + (endCoords.pageX-startCoords.pageX) + "x, " + (endCoords.pageY-startCoords.pageY) + "y");
});
.myelementのスワイプジェスチャーを検出するために使用される簡略化されたコードがあります。元はスライダーギャラリーでした。
$(function() {
var diff, tchs, del = 150,
clk = function(el){
if ( typeof(tchs) !== 'object' ) return; //we have nothing to do
if ( (diff - tchs[tchs.length - 1].pageX) < 0 ) { //swipe right
}
else if ( (diff - tchs[tchs.length - 1].pageX) > 0 ) { //swipe left
}
};
$('.myelement').bind('touchstart touchmove', function(ev){
var oev = ev.originalEvent, el = $(this);
switch( ev.type.charAt(5) ){
case 's': //touch start
diff = oev.pageX;
window.setTimeout(clk, del, el);
break;
case 'm': //touch move
tchs = oev.touches;
break;
}
});
});
UPD:ちなみに、私がMobiOneバージョン2.0.0M2テストセンターソフトウェアを使用したとき、期待どおりにtouchend pageX値が配置されていたため、実際のデバイスにすばやくアクセスできない場合は、実装が悪いように聞こえ、混乱しやすいかもしれません。
UPD2:OK、正のフィードバックに触発された:)右、左、上下のスワイプを検出できる少し複雑なバージョンを実現しましたが、まだクリーンアップする必要がありますが、あなたはアイデアを得ました。
$(function () {
var ftch, // first touch cache
lck = Math.sin(Math.PI / 4); //lock value, sine of 45 deg configurable
var defSwipeDir = function (el, tchs) { // need define swaping direction, for better UX
if (typeof (tchs) !== 'object') return 0; // check if there was any movements since first touch, if no return 0
var ltch = tchs[tchs.length - 1], // last touch object
dx = ltch.pageX - ftch.pageX,
dy = ltch.pageY - ftch.pageY,
hyp = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)),
sin = dy / hyp,
cos = dx / hyp,
dir;
if (Math.abs(cos) >= lck) { // left or right swape
dir = cos > 0 ? 'r' : 'l';
} else { // up or down
dir = sin < 0 ? 'u' : 'd';
}
el.trigger('swipe', dir); // trigger custom swipe event
return dir; // and return direction too
}
$('.myelementTouchDetection').on('touchstart touchmove swipe', function (ev, d) {
var oev = ev.originalEvent,
myelementTouchDetection = $(this),
dir; // you may know swipes on move event too
switch (ev.type) {
case 'touchstart':
ftch = oev;
break;
case 'touchmove':
dir = defSwipeDir(myelementTouchDetection, oev.touches);
return false // cancel default behaiviour
break;
case 'swipe':
switch (d) {
case 'r': // swipe right
console.log('swipe right');
break;
case 'l': // swipe left
console.log('swipe left');
break;
case 'u': // swipe up
console.log('swipe up');
break;
case 'd': // swipe down
console.log('swipe down');
break;
}
break;
}
})
});
ここに私のために働くものがあります...
$('.someClass').bind('touchmove',function(e){
e.preventDefault();
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
var Elm = $(this).offset();
var x = touch.pageX - Elm.left;
var y = touch.pageY - Elm.top;
if(x < $(this).width() && x > 0){
if(y < $(this).height() && y > 0){
//your code here
}
}
});