タッチイベントを理解する


80

一部のライブラリをタッチデバイスで動作させようとしていますが、それらがどのようにサポートされ、どのように動作するかを理解するのに苦労しています。

基本的に5つのタッチイベントがありますが、モバイルブラウザ間ではtouchstartイベントについてのみコンセンサスがあるようです(duh)。テストケースとしてフィドルを作成しました。

Android4を搭載したGalaxyNoteでこれをテストしましたが、デスクトップブラウザでもリンクを確認できます。

目標は、タップ、ダブルタップ、およびロングタップの処理方法を理解することです。特別なことは何もありません。

基本的に、これは何が起こるかです:

Androidの株式ブラウザはタッチイベントを発生しません。それはちょうどタップ、焼成してエミュレートマウスクリックにしようmousedownmouseupclick連続したイベントが、ダブルタップはちょうどthaのページズームイン、ズームアウト。

Chrome for Androidは、指が画面に触れるとタッチスタートイベントを発生させます。それはすぐに十分なリリースだ場合、それはその後、発火mousedownmouseuptouchendそして最後clickのイベント。

ロングタップの場合、約0.5秒後に発火mousedownmouseuptouchend指を離すとclick最後にイベントは発生しません。

動かすと、touchmoveイベントが数回発生し、その後touchcancelイベントが発生します。その後は何も発生せずtouchend、指を離してもイベントは発生しません。

ダブルタップ/アウトズーム機能のトリガーが、イベントごと、それはコンボ発動touchstart-touchevent二度は無いマウスイベントでは、解雇しました。

FirefoxのAndroid用は正しく発火touchstartイベントを、短いタップ火災の場合はmousedownmouseuptouchendおよびclickその後。

ロングタップの場合、発砲しmousedownmouseup最後にtouchendイベント。これらについてはChromeと同じです。

しかし、あなたがあれば、あなたの指を動かす火災があれば、touchmove継続的に(1が期待することとして)それはdoesnのないtouchleave指がイベントリスナーを持つ要素を離れたときにイベントをし、発生しませんtouchcancel指は、ブラウザのビューポートから外れたときに、イベントを。

以下のためにダブルタップ、それだけでクロームのように振る舞います。

Opera MobileはChromeとFirefoxと同じことを短いタップで実行しますが、長押しすると、本当に無効にしたいある種の共有機能がアクティブになります。指を動かしたり、ダブルタップしたりすると、Firefoxと同じように動作します。

Chromeベータ版は通常の短いタップで動作しますが、長いタップの場合はmouseupイベントを発生しなくなります。ちょうどtouchstartmousedown0.5秒後touchend、指を離したときです。指を動かすと、FirefoxやOperaMobileのように動作するようになりました。

ダブルタップの場合、ズームアウト時にタッチイベントは発生しませんが、ズームインした場合にのみ発生します。

Chromeベータ版は最も奇妙な動作を示しますが、ベータ版なので文句は言えません。

問題は、タッチデバイスの最も一般的なブラウザでショートタップ、ロングタップ、ダブルタップを検出しようとする簡単で方法はありますか?

残念ながら、Safariを搭載したiOSデバイス、またはWindows Phone 7 / Phone 8 / RT用のIEでテストすることはできませんが、テストできる方がいらっしゃいましたら、フィードバックをいただければ幸いです。


1
Tocca.jsを試しましたか?gianlucaguarini.github.io/Tocca.jsあらゆる種類のデバイスで欠落しているすべてのタッチイベントを有効にし、約1kbです
Gianluca Guarini

回答:


26

まだ読んでいない場合は、Hammer.jsのソースコードを読むことをお勧めします

https://github.com/hammerjs/hammer.js/blob/master/hammer.js

コメントとコードの間は約1400行で、優れたドキュメントがあり、コードは簡単に理解できます。

作者が多くの一般的なタッチイベントを解決するためにどのように選択したかがわかります。

ホールド、タップ、ダブルタップ、ドラッグ、ドラッグスタート、ドラッグエンド、ドラッグアップ、ドラッグダウン、ドラッグレフト、ドラッグライト、スワイプ、スワイプアップ、スワイプダウン、スワイプレフト、スワイプライト、トランスフォーム、トランスフォームスタート、トランスフォームエンド、回転、ピンチ、ピンチン、ピンチアウト、タッチ(ジェスチャ検出開始) 、リリース(ジェスチャ検出終了)

ソースコードを読んだ後は、タッチイベントがどのように機能するか、ブラウザが処理できるイベントを特定する方法をよりよく理解できると思います。

http://eightmedia.github.io/hammer.js/


興味深いコードは、非常に完全で広範に見えます。分析に時間がかかるかもしれません。
MaxArt 2013

9

驚異的な数のブラウザーにわたるイベントの順序を詳しく説明している、非常に優れたリソースhttps://patrickhlauke.github.io/touch/tests/results/があります。また、定期的に更新されているようです(2016年9月、最終更新日は2016年8月)。

要点は、本質的にすべてのトリガーmouseoverと関連イベントです。ほとんどの場合、タッチイベントもトリガーされます。これは通常touchend前に完了(リーチ)してからmouseover続行しますclick(ページコンテンツへの変更によってこれがキャンセルされない限り)。これらの厄介な例外は、ありがたいことに比較的まれです(サードパーティのAndroidブラウザとBlackBerry Playbook)。

そのリンクされたリソースは、印象的な詳細レベルになります。これは、多くのオペレーティングシステム、デバイス、およびブラウザのテストの最初の3つのサンプルです。

ここに画像の説明を入力してください

重要なポイントのいくつかを要約すると:

モバイルブラウザ

  • リストされているすべてのブラウザーmouseoverは、最初のタップでトリガーされます。一部のWindowsPhoneブラウザーのみが、2回目のタップでトリガーします。
  • すべてのトリガーclick。ページを変更したclick場合にキャンセルするかどうかは指定されていませんmouseover(ほとんどの場合そうだと思います)
  • ほとんどのブラウザでは、トリガmouseover後にtouchstartしてtouchend。これには、iOS7.1 Safari、Android用のストックAndroid、Chrome、Opera、Firefox、および一部(すべてのWindows Phoneブラウザーではない)が含まれます。
  • いくつかのWindowsPhoneブラウザー(すべてのWindows 8 / 8.1および1つのバージョンの10)およびいくつかのサードパーティのAndroidブラウザー(Dolphin、Maxathon、UC)はmouseover touchstartおよびの後にトリガーさtouchendます。
  • BlackberryPlaybookのみがとのmouseovertouchstartでトリガーされますtouchend
  • Opera MiniとPuffin(サードパーティのAndroidブラウザ)のみが不足touchstartまたはtouchend

デスクトップブラウザ

  • 適度に最新バージョンのデスクトップChromeとOperaは、モバイル版と同じように動作しtouchstarttouchendその後にmouseover。が続きます。
  • FirefoxおよびMicrosoftブラウザー(IE <= 11およびEdgeの多くのバージョン)はtouchstarttouchendイベントをトリガーしません。
  • Macにはデータがありませんが、Macのタッ​​チスクリーンインターフェイスが不足しているためtouchstart、おそらくMaブラウザはサポートしていませんtouchend

支援技術と組み合わせたブラウザには、信じられないほどの量のデータもあります。


3

はい、でタイマーを開始しtouchstartて終了しtouchend、そこから選択を行うことができます。

また、作成することもできます...たとえば、スワイプするtouchmoveと、「指」の座標を取得して、トリガーされる前touchendに移動した量を確認できます。

タッチイベントライブラリを使用するよりも簡単な方法があるかどうかはわかりませんが、単純な「タップ」、「ダブルタップ」、「スワイプ」イベント用に簡単に作成できると思います。


1
それについて考え、上記のブラウザの動作を考えると、それはまったく簡単ではないことを認めるでしょう。たとえば、要素に触れた後、指を要素の外側に移動してから指を離すと、有効な「タップ」にtouchleaveはなりませんが、発射されないため、検出できません。
MaxArt 2013年

あなたは良い点を指摘しますが、e.targetタッチスタートで要素(私は信じています)をキャプチャするような適切なコーディングで、それはタッチエンドの要素と同じですか?いいえの場合、それは有効なタップではなく、トラップです。ライブラリのコーディングが簡単だと言っているわけではありませんが、実際には「難しい」とは言えません。「中」とランク付けします。これが難しくなく、stackoverflow xDに戻ることができれば何が楽しいのでしょうか
Alexandru Calin 2013年

ライブラリのコーディングは私にとって問題ではありません。やりがいがあり、満足感があり、やや楽しいと思います。しかし、あなたのコメントは解決策を示唆しているだけですが、どのようにそれを構築しますか?touchstartイベントに関する情報はどこに保管していますか?touchstartその間に2番目のイベントが発生した場合(マルチタッチディスプレイ)はどうなりますか?ロングタップはどのように処理しますか?を使用していますがsetTimeout、その間に指が要素を離れるとどうなりますか?タッチイベントが発生しない場合、どのようにそれを検出しますか?などなど...もちろん試してみますが、タッチイベントの深い分析を見つけたいと思っていました。
MaxArt 2013年

タッチエンドイベントを発生させずに2番目のタッチスタートイベントを発生させることはできないため、2回の同時タップを行うことはできないため、問題はありません。変数に情報を保持し、タッチエンドでリセットします
Alexandru Calin

それはあなたが、正しくないのですができ秒を持っているtouchstart最初の前touchendに発生します。さらに、あなたの答えをもう一度考えると、指が要素の外に移動された場合でもtargettouchendイベントのプロパティは常にタッチが開始された要素と等しいため、それは役に立たないという結論につながります
MaxArt 2013年

3

これがAndroid4.3でのタッチイベントとマウスイベントに関する私の最新の観察結果です

Opera、Firefox、Chromeは標準的な動作をしているようです

  1. スワイプ(touchstart-touchmove-touchend)の場合:

    1. マウスイベント(マウスオーバーを除く)は発生しません。
    2. マウスオーバーは、touchstartとtouchendが同じ要素で発生した場合にのみ発生します。(touchstart-touchmove-touchend-mouseover)
    3. タッチスタートでデフォルトが防止されている場合:デフォルトのスワイプ動作は機能しません。マウスイベントの発生に関しては変更はありません。
  2. タップ時(touchstart-touchend):

    1. すべてのマウスイベントmouseover-mousemove-mousedown-mouseup-clickfire遅延後
    2. タッチスタートでデフォルトが防止されている場合:マウスオーバーのみが発生します。

Androidのデフォルトブラウザには、いくつかの非標準的な動作があります

  1. マウスオーバーはタッチスタートの前に発生します。つまり、マウスオーバーは常に発生します。
  2. タッチスタートでデフォルトが禁止されている場合でも、すべてのマウスイベントはTapで発生します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.