Czytałem, że mobilna Safari ma 300 ms opóźnienia w przypadku kliknięć od momentu kliknięcia łącza / przycisku do momentu uruchomienia zdarzenia. Powodem opóźnienia jest oczekiwanie, aby zobaczyć, czy użytkownik zamierza dwukrotnie kliknąć, ale z perspektywy UX czekanie 300 ms jest często niepożądane.
Jednym z rozwiązań pozwalających wyeliminować to 300 ms opóźnienia jest użycie obsługi „dotknięcia” w jQuery Mobile. Niestety nie jestem zaznajomiony z tym frameworkiem i nie chcę ładować jakiegoś dużego frameworka, jeśli potrzebuję tylko jednego lub dwóch wierszy kodu zastosowanych touchend
we właściwy sposób.
Podobnie jak wiele innych witryn, moja witryna ma wiele takich zdarzeń kliknięcia:
$("button.submitBtn").on('click', function (e) {
$.ajaxSubmit({... //ajax form submisssion
});
$("a.ajax").on('click', function (e) {
$.ajax({... //ajax page loading
});
$("button.modal").on('click', function (e) {
//show/hide modal dialog
});
Chciałbym pozbyć się 300 ms opóźnienia WSZYSTKICH tych zdarzeń kliknięcia za pomocą pojedynczego fragmentu kodu, takiego jak ten:
$("a, button").on('tap', function (e) {
$(this).trigger('click');
e.preventDefault();
});
Czy to zły / dobry pomysł?
źródło
Odpowiedzi:
Niektóre przeglądarki mobilne eliminują teraz 300 ms opóźnienia kliknięcia, jeśli ustawisz obszar wyświetlania. Nie musisz już używać obejść.
<meta name="viewport" content="width=device-width, user-scalable=no">
Jest to obecnie obsługiwane Chrome na Androida , Firefox na Androida i Safari na iOS
Jednak w iOS Safari dwukrotne dotknięcie to gest przewijania na stronach, których nie można powiększyć. Z tego powodu nie mogą usunąć opóźnienia 300 ms . Jeśli nie mogą usunąć opóźnienia na stronach, których nie można powiększyć, jest mało prawdopodobne, aby usunęli je na stronach, które można powiększać.Telefony z systemem Windows zachowują również opóźnienie 300 ms na stronach, których nie można powiększyć, ale nie mają alternatywnego gestu, takiego jak iOS, więc mogą usunąć to opóźnienie, tak jak ma to miejsce w Chrome.Możesz usunąć opóźnienie w Windows Phone za pomocą:Źródło: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away
UPDATE 2015 grudzień
Do tej pory WebKit i Safari na iOS miały 350 ms opóźnienia, zanim pojedyncze dotknięcie aktywowało linki lub przyciski, aby umożliwić ludziom powiększanie stron za pomocą podwójnego dotknięcia. Chrome zmienił to już kilka miesięcy temu, używając inteligentniejszego algorytmu do wykrywania tego, a WebKit zastosuje podobne podejście . Artykuł zawiera świetne informacje o tym, jak przeglądarki współpracują z gestami dotykowymi i jak przeglądarki mogą być o wiele inteligentniejsze niż obecnie.
UPDATE 2016 marzec
W Safari na iOS, 350 ms czasu oczekiwania na wykrycie drugiego stuknięcia został usunięty, aby utworzyć odpowiedź „fast-tap”. Jest to włączone dla stron, które deklarują obszar roboczy z wartością width = device-width lub user-scalable = no. Autorzy mogą również zdecydować się na zachowanie szybkiego stuknięcia w określone elementy, używając CSS,
touch-action: manipulation
jak opisano tutaj (przewiń w dół do nagłówka „Stylowe szybkie dotknięcie ”) i tutaj .źródło
Ta wtyczka -FastClick opracowana przez Financial Times robi to doskonale dla Ciebie!
Upewnij się jednak, że dodajesz
event.stopPropagation();
i / lubevent.preventDefault();
bezpośrednio po funkcji kliknięcia, w przeciwnym razie może działać dwa razy tak, jak u mnie, tj .:$("#buttonId").on('click',function(event){ event.stopPropagation(); event.preventDefault(); //do your magic });
źródło
fastclick
robi swoją magię tylko na urządzeniach dotykowych, które mają problem z opóźnieniem (w innym przypadku jest to automatycznie pomijane ). Jednak samo dodaniestopPropagation
&preventDefault
po każdym zdarzeniu kliknięcia może mieć niepożądany wpływ na wszystkie programy obsługi zdarzeń we wszystkich przeglądarkach.Wiem, że to jest stare, ale czy nie możesz po prostu przetestować, czy przeglądarka obsługuje „dotyk”? Następnie utwórz zmienną, która jest albo „dotknięta”, albo „kliknij” i wykorzystaj tę zmienną jako zdarzenie, które zostanie przypisane do Twojego elementu?
var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click'; $('#element').on(clickOrTouch, function() { // do something });
Tak więc ten przykładowy kod sprawdza, czy zdarzenie „touchend” jest obsługiwane w przeglądarce, a jeśli nie, to używamy zdarzenia „click”.
(Edycja: zmieniono „touchend” na „ontouchend”)
źródło
Natknąłem się na niezwykle popularną alternatywę o nazwie Hammer.js (strona Github), która moim zdaniem jest najlepszym podejściem.
Hammer.js jest bardziej w pełni funkcjonalną biblioteką dotykową (ma wiele poleceń machnięcia) niż Fastclick.js (najbardziej pozytywna odpowiedź).
Uważaj jednak: szybkie przewijanie na urządzeniach mobilnych ma tendencję do blokowania interfejsu użytkownika, gdy używasz Hammer.js lub Fastclick.js. Jest to poważny problem, jeśli Twoja witryna ma kanał aktualności lub interfejs, w którym użytkownicy będą dużo przewijać (wygląda na to, że większość aplikacji internetowych). Z tego powodu w tej chwili nie używam żadnej z tych wtyczek.
źródło
W jakiś sposób wyłączenie powiększenia wydaje się wyłączać to małe opóźnienie. Ma to sens, ponieważ dwukrotne dotknięcie nie jest już potrzebne.
Jak mogę „wyłączyć” powiększenie mobilnej strony internetowej?
Należy jednak pamiętać o wpływie, jaki będzie to miało na użyteczność. Może być przydatny w przypadku stron internetowych zaprojektowanych jako aplikacje, ale nie powinien być używany w przypadku bardziej ogólnych stron „statycznych” IMHO. Używam go do projektu dla zwierząt domowych, który wymaga małego opóźnienia.
źródło
Niestety nie ma na to prostego sposobu. Tak więc samo użycie
touchstart
lubtouchend
pozostawi Cię z innymi problemami, na przykład gdy ktoś zacznie przewijać po kliknięciu przycisku. Używamy zepto od jakiegoś czasu i nawet z tym naprawdę dobrym frameworkiem są pewne problemy, które pojawiły się z czasem. Wiele z nich jest zamkniętych , ale wydaje się, że nie jest to pole do prostego rozwiązania.Mamy to rozwiązanie do obsługi kliknięć linków na całym świecie:
$(document.body). on('tap', 'a',function (e) { var href = this.getAttribute('href'); if (e.defaultPrevented || !href) { return; } e.preventDefault(); location.href= href; }). on('click', 'a', function (e) { e.preventDefault(); });
źródło
tap
rozwiązania, które opublikowałem, i nie uwzględniajtap
wydarzeń według elementu?tap
rozwiązanie. Zaktualizuję moją odpowiedź.tap
rozwiązanie wyglądałoby tak samo jak twoje w tym przypadku?Szukałem łatwego sposobu bez jQuery i bez biblioteki fastclick. To działa dla mnie:
var keyboard = document.getElementById("keyboard"); var buttons = keyboard.children; var isTouch = ("ontouchstart" in window); for (var i=0;i<buttons.length;i++) { if ( isTouch ) { buttons[i].addEventListener('touchstart', clickHandler, false); } else { buttons[i].addEventListener('click', clickHandler, false); } }
źródło
Tylko po to, aby podać dodatkowe informacje.
W systemie iOS 10
<button>
s na mojej stronie nie mogły być uruchamiane w sposób ciągły. Zawsze było opóźnienie.Próbowałem fastclick / Hammer / tapjs / zastępując kliknięcie za pomocą Touchstart, wszystko zawiodło.
UPDATE: powodem wydaje się być to, że przycisk jest zbyt blisko krawędzi! przesuń go w pobliże środka i nie ma opóźnienia!
źródło
Powinieneś jawnie zadeklarować tryb pasywny :
window.addEventListener('touchstart', (e) => { alert('fast touch'); }, { passive : true});
źródło
W jQuery można powiązać zdarzenie „touchend”, które uruchamia kod natychmiast po dotknięciu (działa jak klawisz w klawiaturze). Przetestowano na aktualnych wersjach tabletów Chrome i Firefox. Nie zapomnij także o „kliknięciu” w przypadku laptopów z ekranem dotykowym i urządzeń stacjonarnych.
jQuery('.yourElements').bind('click touchend',function(event){ event.stopPropagation(); event.preventDefault(); // everything else });
źródło