ボタンのクリックを処理しようとしています。「ボタン」は、子も含めることができるカスタム div です。クリック コールバックは、ユーザーが要素内でクリックとリリースの両方を行ったときに発生する必要があります。ユーザーが内側をクリックしてからドラッグして外側に放した場合、ハンドラーは起動しません。デスクトップとモバイルの両方でこれを機能させる必要があるため、イベントを使用mousedown/mouseup
してtouchstart/touchend
います。
ユーザーが外部でリリースした場合でも、ボタン クラスを「押された」から「通常」に変更する必要があるため、ドキュメント上でリリース イベントをキャプチャするリスナーを追加する必要があります。
var $myElement = $("#myelement"); //This is a div and can also contain children.
$myElement.on("mousedown touchstart", function(e){
$(this).addClass("pressed");
$(document).on("mouseup touchend", function listener(e){
$myElement.removeClass("pressed");
$(document).off("mouseup touchend", listener);
var $target = $(e.target);
if ($target.is($myElement) || $target.parents().is($myElement)){
//FIXME
alert("Inside!");
//do something here
return false;
} else {
//FIXME
alert("Outside!");
//let event bubble
}
});
return false;
});
クリックでは問題なく動作しますが、タッチ イベントでは期待どおりに動作しません。これを Chrome for Android でテストし、要素を押してからドラッグすると、「Inside!」アラートが表示されます。
問題は次の状態にあります。
if ($target.is($myElement) || $target.parents().is($myElement)){
touchend
ボタンまたは子のいずれかでイベントが発生したかどうかを確認しようとしています。ボタンに子がない場合、ボタンをクリックしてから離すと、OR 句の最初の部分が true に解決されます。ボタンに子があり、子をクリックし、画面の他の部分で離すと、句の 2 番目の部分が true になります。
このコードの何が問題になっていますか?
前もって感謝します。
更新
BlackBerry 10 でも同じ結果でテストしました。どうやら、イベントのターゲットtouchend
はボタン (または子) です。外側をクリックした場合でもそうです。これはどのように機能するはずですか?
更新
そしてここに理由があります。これは、W3Cドキュメントがイベントについて言っていることです:
このイベントのターゲットは、タッチ ポイントがターゲット要素のインタラクティブ領域の外に移動した場合でも、このタッチ ポイントが表面に配置されたときに touchstart イベントを受け取ったものと同じ要素でなければなりません。
私には意味がありませんが、とにかくこれは私の問題を説明しています。touchend
指が離された要素でイベントが呼び出されると想定していました。別のアプローチを使用して、指のリリースを外部で検出することは可能でしょうか?
UPDATEを使用して要素を取得するために
、の座標を取得しようとしました。問題は、このイベントに座標が含まれていないことです (およびリストが空です)。デバッガーでイベントを徹底的に調べましたが、元のイベント以外に座標を取得する方法はありません。次に、最後のイベントをキャッシュしてそこから座標を取得できると考えましたが、このイベントには独自の座標がありません! 役に立たないのに、一体なぜこの 2 つのイベントが存在するのでしょうか。そして、このアプローチを iOS、Android、BB10 でテストしましたが、同じ結果が得られました。touchevent
document.elementFromPoint
changedTouches
touches
touchmove
私は断念しました。ユーザーが外部をクリックした場合でも、コールバックを呼び出します。これが 2013 年のものだとは信じられませんが、これを行う (簡単な) 方法はありませんか? ドラッグ アンド ドロップ API を使用できましたが、これによれば、モバイルではサポートされていません (モバイル Web 開発が大好きです)。