Zrozumienie zdarzeń dotykowych

80

Próbuję sprawić, by niektóre z moich bibliotek współpracowały z urządzeniami dotykowymi, ale ciężko mi jest dowiedzieć się, w jaki sposób są obsługiwane i jak działają.

Zasadniczo jest 5 zdarzeń dotykowych , ale wydaje się, że istnieje konsensus między przeglądarkami mobilnymi tylko w sprawie touchstartwydarzenia (tak). Stworzyłem skrzypce jako przypadek testowy.

Przetestowałem to na moim Galaxy Note z Androidem 4 na pokładzie, ale możesz też sprawdzić link w przeglądarce na komputerze.

Celem jest próba zrozumienia, jak radzić sobie z dotknięciem, podwójnym i długim dotknięciem. Nic fajnego.

Zasadniczo dzieje się tak:

Przeglądarka giełdowa Androida nie uruchamia zdarzeń dotykowych. To właśnie próbuje naśladować kliknięć myszką z kranów, wypalanie mousedown, mouseupi clickwydarzeń kolejno, ale podwójne zawory tylko powiększać i pomniejszać tha strony.

Chrome na Androida uruchamia zdarzenie startu dotykowego, gdy palec dotyka ekranu. Jeśli jest wydany na tyle wcześnie, pożary następnie mousedown, mouseup, touchenda na koniec clickimprezy.

W przypadku długiego kranu , po około pół sekundy pożary mousedowni mouseup, a touchendgdy palec zostanie zniesione, bez clickwypadku na końcu.

Jeśli poruszysz palcem , touchmovekilka razy wyzwala touchcancelzdarzenie, po czym wyzwala zdarzenie, a potem nic się nie dzieje, nawet touchendzdarzenie po podniesieniu palca.

A double tap wyzwala zoom in / out funkcji, ale wydarzenie mądry pożary kombi touchstart- toucheventdwa razy, bez żadnych zdarzeń myszy zwolniony.

Firefox dla Androida prawidłowo pożary touchstartzdarzenia, aw przypadku krótkich pożarów kranu mousedown, mouseup, touchenda clickpotem.

W przypadku długiego kranu odpala mousedown, mouseupa na końcu touchendzdarzenia. Tak samo jest z Chrome w przypadku tych rzeczy.

Ale jeśli poruszasz palcem , jeśli jest uruchamiany w sposób touchmoveciągły (jak można się spodziewać), ale nie uruchamia touchleavezdarzenia, gdy palec opuszcza element z detektorem zdarzeń, i nie uruchamia touchcancelzdarzenia, gdy palec wyjdzie z widoku przeglądarki .

W przypadku dwukrotnego dotknięcia zachowuje się tak jak Chrome.

Opera Mobile robi to samo co Chrome i Firefox po krótkim dotknięciu, ale w przypadku długiego naciśnięcia aktywuje jakąś funkcję udostępniania, którą naprawdę chcę wyłączyć. Jeśli poruszysz palcem lub dwukrotnie dotknij, zachowuje się tak jak Firefox.

Chrome beta ma zwykle na krótkie krany, ale w przypadku długich kranów nie ognia mouseupzdarzenie już, po prostu touchstart, po czym mousedownpo pół sekundy, a touchendgdy palec zostanie zniesione. Kiedy palec zostanie przesunięty, zachowuje się jak Firefox i Opera Mobile.

W przypadku podwójnego dotknięcia nie uruchamia zdarzeń dotykowych podczas pomniejszania , ale tylko podczas powiększania.

Chrome beta wykazuje najdziwniejsze zachowanie, ale nie mogę narzekać, ponieważ jest to wersja beta.

Pytanie brzmi : czy istnieje prosty i sposób na wykrycie krótkich, długich i podwójnych dotknięć w najpopularniejszych przeglądarkach urządzeń dotykowych?

Szkoda, że ​​nie mogę go przetestować na urządzeniach iOS z Safari lub IE dla Windows Phone 7 / Phone 8 / RT, ale jeśli niektórzy z was mogą, Wasza opinia byłaby bardzo wdzięczna.

MaxArt
źródło
1
Czy próbowałeś Tocca.js? gianlucaguarini.github.io/Tocca.js Umożliwia wszystkie brakujące zdarzenia dotykowe na dowolnym urządzeniu i to tylko około 1kb
Gianluca Guarini

Odpowiedzi:

26

Jeśli jeszcze tego nie zrobiłeś, proponuję przeczytać kod źródłowy Hammer.js

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

Pomiędzy komentarzami a kodem jest około 1400 linii, jest świetna dokumentacja, a kod jest łatwy do zrozumienia.

Możesz zobaczyć, w jaki sposób autor zdecydował się rozwiązać wiele typowych zdarzeń dotykowych:

przytrzymaj, stuknij, podwójnie stuknij, przeciągnij, przeciągnij, rozpocznij, przeciągnij, przeciągnij, przeciągnij, przeciągnij, przeciągnij, przeciągnij, przesuń, przesuń w górę, przesuń w dół, przesuń w lewo, swiperight, transform, transformstart, transformend, obróć, szczyp, szczypanie, szczypanie, dotyk (rozpoczyna się wykrywanie gestów) , puść (kończy się wykrywanie gestów)

Myślę, że po przeczytaniu kodu źródłowego znacznie lepiej zrozumiesz, jak działają zdarzenia dotykowe i jak zidentyfikować, które zdarzenia przeglądarka jest w stanie obsłużyć.

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

vrtis
źródło
Ciekawy fragment kodu, wydaje się dość kompletny i obszerny. Analiza tego może zająć trochę czasu.
MaxArt,
9

Istnieje naprawdę doskonały zasób https://patrickhlauke.github.io/touch/tests/results/, który szczegółowo opisuje kolejność zdarzeń w oszałamiającej liczbie przeglądarek. Wydaje się również, że jest regularnie aktualizowany (we wrześniu 2016 r. Ostatnio zaktualizowano w sierpniu 2016 r.).

Istota jest taka, że zasadniczo wszystko wyzwala mouseoveri powiązane zdarzenia; większość wyzwala również zdarzenia dotykowe, które zwykle kończą się (sięgają touchend) przed, mouseovera następnie trwają click(chyba że zmiana treści strony anuluje to). Te niezręczne wyjątki są na szczęście stosunkowo rzadkie (przeglądarki Androida innych firm i poradnik na temat blackberry).

Ten połączony zasób ma imponujący poziom szczegółowości. Oto przykład pierwszych trzech z wielu, wielu testów systemów operacyjnych, urządzeń i przeglądarek:

wprowadź opis obrazu tutaj

Podsumowując niektóre kluczowe punkty:

Przeglądarki mobilne

  • Wszystkie wymienione przeglądarki uruchamiają mouseoversię po pierwszym dotknięciu. Tylko niektóre przeglądarki Windows Phone wyzwalają go po drugim dotknięciu.
  • Wszystkie wyzwalacze click. Nie określa, które anuluj, clickjeśli mouseoverzmieni stronę (wydaje mi się, że większość to robi)
  • Większość przeglądarek uruchamia się mouseoverpo touchstarti touchend. Obejmuje to iOS7.1 Safari, standardowe systemy Android, Chrome, Opera i Firefox na Androida i niektóre (nie wszystkie przeglądarki na Windows Phone)
  • Kilka przeglądarek Windows Phone (wszystkie Windows 8 / 8,1 i jedna wersja na 10) i kilka 3rd-Party Android przeglądarek (Delfin, Maxathon, UC) spust mouseover po touchstart i touchend.
  • Tylko Blackberry Playbook uruchamia się mouseovermiędzy touchstartatouchend
  • Tylko Opera Mini i Puffin (przeglądarka Androida innej firmy) nie mają touchstartlub touchend.

Przeglądarki komputerowe

  • Racjonalnie aktualne wersje komputerowej przeglądarki Chrome i Opery zachowują się jak ich mobilne odpowiedniki, touchstarta touchendza nimi podążają mouseover.
  • Przeglądarki Firefox i Microsoft (IE <= 11 i wiele wersji Edge) nie wyzwalają żadnych zdarzeń touchstarti touchend.
  • Brak danych na komputerach Mac, ale prawdopodobnie nie obsługują przeglądarek Ma touchstarti touchendbiorąc pod uwagę niedobór interfejsów dotykowych w Macach.

Istnieje również niesamowita ilość danych w przeglądarkach w połączeniu z technologiami pomocniczymi.

user56reinstatemonica8
źródło
3

Tak, możesz uruchomić stoper o godzinie touchstarti zakończyć go, touchenda następnie dokonać wyboru.

Możesz także zrobić ... powiedzmy machnięcie, moje wyzwalanie touchmovemożesz uzyskać współrzędne "palca" i zobaczyć, ile podróżowałem, zanim touchendzostanie wyzwolony.

Nie wiem, czy istnieje prostszy sposób niż korzystanie z biblioteki zdarzeń dotykowych, ale przypuszczam, że można łatwo napisać jedną dla prostych zdarzeń „dotknięcia”, „dwukrotnego dotknięcia”, „przesunięcia”.

Alexandru Calin
źródło
1
Jeśli pomyślisz o tym i weźmiesz pod uwagę zachowanie powyższych przeglądarek, przyznasz, że nie jest to wcale łatwe. Na przykład, jeśli dotkniesz elementu, a następnie przesuniesz palec na zewnątrz elementu, a następnie podniesiesz palec, nie byłoby to prawidłowe „stuknięcie”, ale nie możesz go wykryć, ponieważ touchleavenigdy nie jest uruchamiany.
MaxArt
Masz rację, ALE; z odpowiednim kodowaniem, takim jak uchwycenie elementu e.target(jak sądzę) na touchstart, czy jest równy elementowi na touchstarcie? Jeśli nie, to nie jest prawidłowy kran, to pułapka. Nie mówię, że kodowanie biblioteki byłoby łatwe, ale nie jest tak naprawdę „trudne”, oceniłbym ją jako „średnią” + jaka jest frajda, jeśli nie stanowi wyzwania i sprawia, że ​​wracamy na stackoverflow xD
Alexandru Calin
Kodowanie biblioteki nie byłoby dla mnie problemem, uważam to za wyzwanie, satysfakcję i nieco zabawę. Ale twój komentarz tylko wskazuje na rozwiązanie, ale jak je zbudujesz? Gdzie przechowujesz informacje o touchstartwydarzeniu? Co się stanie, jeśli w touchstartmiędzyczasie uruchomione zostanie drugie zdarzenie (wyświetlacz wielodotykowy)? Jak radzisz sobie z długimi kranami? Używając setTimeout, ale co, jeśli palec w międzyczasie opuści element? Jak to wykryjesz, jeśli żadne zdarzenia dotykowe nie są wyzwalane? I tak dalej ... Spróbuję oczywiście, ale miałem nadzieję, że znajdę głęboką analizę wydarzeń dotykowych.
MaxArt
Nie możesz uruchomić drugiego zdarzenia touchstart bez wyzwalania zdarzenia touchstart, dlatego nie możesz mieć dwóch jednoczesnych dotknięć, więc nie ma problemu. Zachowałbyś informacje w zmiennych i zresetowałbyś je na touchend
Alexandru Calin
To jest błędne, to może mieć drugi touchstartprzed pierwszym touchendwystępuje. Co więcej, ponowne myślenie o Twojej odpowiedzi prowadzi do wniosku, że to nie pomoże, ponieważ targetwłaściwość touchendzdarzenia zawsze jest równa elementowi, w którym rozpoczął się dotyk, nawet jeśli palec został przesunięty poza element!
MaxArt,
3

Oto moje najnowsze obserwacje dotyczące zdarzeń dotyku i myszy w systemie Android 4.3

Wygląda na to, że Opera, Firefox i Chrome mają standardowe zachowanie

  1. On Swipe (touchstart-touchmove-touchchend):

    1. Żadne zdarzenie myszy (z wyjątkiem przesunięcia myszy) nie jest uruchamiane.
    2. Funkcja Mouseover uruchamia się tylko wtedy, gdy touchstart i touchend występują na tym samym elemencie. (touchstart-touchmove-touchend-mouseover)
    3. Jeśli opcja domyślna jest wyłączona przy Touchstart: domyślne zachowanie związane z przesuwaniem nie działa. nie nastąpiły żadne zmiany dotyczące uruchamiania zdarzeń myszy.
  2. Po dotknięciu (touchstart-touchchend):

    1. Wszystkie zdarzenia myszy mouseover-mousemove-mousedown-mouseup-click uruchamiają się po opóźnieniu
    2. Jeśli opcja domyślna jest zablokowana przy Touchstart: uruchamiany jest tylko wskaźnik myszy.

Domyślna przeglądarka Androida ma kilka niestandardowych zachowań :

  1. Funkcja Mouseover uruchamia się przed startem dotykowym, co oznacza, że ​​funkcja Mouseover zawsze uruchamia się.
  2. Wszystkie zdarzenia myszy uruchamiają się po dotknięciu, nawet jeśli domyślne ustawienie jest wyłączone podczas startu dotykowego.
Semra
źródło