Profesjonalny uzależniony od Internetu • Entuzjasta gier • Twórca technologii
Profesjonalny uzależniony od Internetu • Entuzjasta gier • Twórca technologii

Sześć rzeczy, których nauczyłem się o gumowym przewijaniu w iOS Safari

Aby naprawić problem z przewijaniem w Safari na iOS, musiałem stworzyć własną, prostą stronę testową!
Ta strona została przetłumaczona z języka angielskiego przez moich niezwykle zmotywowanych stażystów ds. sztucznej inteligencji, dla Państwa wygody. Wciąż się uczą, więc mogło umknąć im kilka błędów. Aby uzyskać najdokładniejsze informacje, prosimy o zapoznanie się z wersją angielską.
Dom Blog Sześć rzeczy, których nauczyłem się o gumowym przewijaniu w iOS Safari

Prosimy pamiętać, że ten wpis na blogu został opublikowany w czerwcu 2015 roku, więc w zależności od tego, kiedy go czytasz, niektóre fragmenty mogą być nieaktualne. Niestety, nie zawsze jestem w stanie aktualizować te wpisy na bieżąco, aby zapewnić poprawność informacji.

Aby naprawić niedawny problem z przewijaniem w Safari na iOS, musiałem stworzyć własną prostą stronę testową, a następnie zastosować wszystkie informacje i kombinacje, które udało mi się znaleźć w internecie, aby spróbować rozwiązać ten problem.

Poniżej znajduje się krótkie podsumowanie tego, co udało mi się odkryć podczas tego procesu.

Moja strona testowa

Moja testowa strona była całkiem prosta. Składała się z danych mockowych w statycznym divie, reprezentujących „stronę”, oraz z nieruchomego divu, który wyświetlał się nad stroną jako „menu”, tak jak to wygląda.

Zrzut ekranu otwartego bocznego menu HTML w Safari na iOS

Cały kod źrółdowy tej strony można znaleźć na dole tego wpisu na blogu.

Zrozumienie domyślnego zachowania

Pierwszą rzeczą, jaką zrobiłem, było zrozumienie domyślnego zachowania Safari na iOS. Najbardziej charakterystycznym spostrzeżeniem było to, że gdy przewinąłeś do samego końca menu, ciało strony wykazywało 'efekt gumki' - funkcja zakodowana na stałe w Safari.

animowany zrzut ekranu z problematycznym efektem gumowego odbicia w iOS Safari na dole strony

To samo zdarzyło się, gdy przewinięto do samej góry menu.

animowany zrzut ekranu ilustrujący problematyczny efekt gumki w iOS Safari na górze strony

Jednak pierwszym problemem, jaki zauważyłem, było to, że jeśli ciągle przewijasz aż na samą górę lub na sam dół, Safari zaczyna wyświetlać problemy z renderowaniem zarówno w tle strony, jak i w menu.

Nie wiem, dlaczego, ale podejrzewam, że to ma związek z funkcją efektu gumowego rozciągania.

animowany zrzut ekranu ilustrujący problem z glitchującym iOS Safari na dole strony

Zrozumienie, co robi reguła CSS "-webkit-overflow-scrolling"

Kolejną rzeczą, którą zrobiłem, było zastosowanie reguły CSS -webkit-overflow-scrolling do menu, co umożliwia przewijanie z efektem momentum.

Jak widać na poniższym obrazku, przewijanie nadal działa po przeciągnięciu palcem.

prezentujemy problem z przewijaniem z efektem momentum w iOS Safari

Ale podczas przewijania aż do samego początku lub końca pojawia się także efekt gumki, jak pokazano poniżej.

prezentuje problem przewijania opartego na momencie w iOS Safari, z efektem gumowego rozciągania

Użytkownik musi poczekać, aż efekt gumki zakończy się.

Podczas testów zauważyłem również, że w trakcie trwania efektu sprężynowego użytkownik nie może przenieść fokusu na inny element, dopóki animacja nie zakończy się w pełni.

W poniższym przykładzie najpierw przewijam stronę w tle, a potem próbuję szybko przewinąć menu, ale kończę przewijaniem dalej strony w tle.

pokazując, że na iOS Safari tło strony jest przewijane

Jednak jeśli poczekam chwilę, aż efekt się skończy, mogę wtedy przewijać menu.

pokazanie oczekiwania na zakończenie efektu gumki w Safari na iOS

Jak zapobiec przewijaniu strony w tle

Podczas testów zauważyłem również, że gdy efekt gumowego rozciągania jest aktywny, użytkownik nie może przenieść fokusu na inny element, dopóki animacja nie zakończy się całkowicie.

Na podstawie tej odpowiedzi z Stack Overflow, możesz zapewnić, że elementy z disable-scrolling nie wykonują domyślnej akcji przewijania, gdy dochodzi do zdarzenia touchmove.

document.ontouchmove = function(event) { var isTouchMoveAllowed = true, target = event.target; while (target !== null) { if (target.classList && target.classList.contains('disable-scrolling')) { isTouchMoveAllowed = false; break; } target = target.parentNode; } if (!isTouchMoveAllowed) { event.preventDefault(); } };

Następnie zastosuj klasę disable-scrolling do elementu div strony:

<div class="page disable-scrolling">

To działa w miarę, ale bardziej szczegółowe testy pokazują, że strona w tle nadal czasami przewija się, gdy dojdziesz do samej góry lub dołu menu.

pokazując, że tło wciąż się przewija

Jak zapobiec przewijaniu strony w tle

Stosując tę poprawkę, możliwe jest zapobieganie overscrollowi. Oznacza to, że gdy element zostanie przewinięty aż do samej góry lub dołu, przewijanie nie przenosi się dalej na ciało strony.

W rezultacie niemożliwe jest przewijanie zawartości strony, co także zapobiega wystąpieniu efektu gumowego przy przewijaniu.

function removeIOSRubberEffect(element) { element.addEventListener("touchstart", function() { var top = element.scrollTop, totalScroll = element.scrollHeight, currentScroll = top + element.offsetHeight; if (top === 0) { element.scrollTop = 1; } else if (currentScroll === totalScroll) { element.scrollTop = top - 1; } }); } removeIOSRubberEffect(document.querySelector(".scrollable"));

Co robi ten fragment JavaScriptu? Zapobiega dotarciu elementu do samego górnego ani dolnego krańca, utrzymując go zaledwie 1 piksel od tych krawędzi.

Jeżeli pozycja przewijania nigdy nie dotrze do samej góry ani do samego dołu, nadmierne przewijanie nigdy się nie zdarzy.

Przykład zapobiegania przewijaniu poza zakres treści: nigdy nie docieramy do samej góry ani do samego końca

Jak zapobiegać overscrollowi prowadzącemu do strony w tle

Jeśli chcesz usunąć efekt gumowego rozciągania z menu — czy to ze względów estetycznych, czy też, jak w moim przypadku, z powodu dodatkowych problemów z renderowaniem — po prostu usuń regułę CSS -webkit-overflow-scrolling.

Jednak, jak widać poniżej, tracisz także płynność przewijania.

pełne demo zapobiegające efektowi gumowego przewijania w iOS Safari

Cały kod źródłowy strony

Oto pełny kod źródłowy tej strony.

<!-- License MIT, Author Special Agent Squeaky (specialagentsqueaky.com) --> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="minimum-scale=1.0, width=device-width, maximum-scale=1.0, user-scalable=no, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style> .page{ font-size: 24px; overflow: scroll; } .menu{ position: fixed; top: 0; bottom: 0; left: 0; width: 80%; background: gray; z-index: 1; font-size: 10px; overflow: scroll; /* uncomment to get smooth momentum scroll, but also a rubber band effect */ /*-webkit-overflow-scrolling: touch;*/ } .menu-item{ padding: 10px; background: darkgray; font-size: 24px; } </style> </head> <body> <div class="menu scrollable"> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> <div class="menu-item">hello world</div> </div> <div class="page disable-scrolling"> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </div> <script> document.ontouchmove = function(event) { var isTouchMoveAllowed = true, target = event.target; while (target !== null) { if (target.classList && target.classList.contains('disable-scrolling')) { isTouchMoveAllowed = false; break; } target = target.parentNode; } if (!isTouchMoveAllowed) { event.preventDefault(); } }; function removeIOSRubberEffect(element) { element.addEventListener("touchstart", function() { var top = element.scrollTop, totalScroll = element.scrollHeight, currentScroll = top + element.offsetHeight; if (top === 0) { element.scrollTop = 1; } else if (currentScroll === totalScroll) { element.scrollTop = top - 1; } }); } removeIOSRubberEffect(document.querySelector(".scrollable")); </script> </body> </html>

Napisane przez Special Agent Squeaky. Pierwsze opublikowanie 2015-06-10. Ostatnia aktualizacja 2015-06-10.

📺 Obejrzyj najnowszy film Squeaky!

Jak dodać proste napisy w czasie rzeczywistym do Twojej transmisji na żywo