Profesionální internetový závislák • Herní nadšenec • Technologický tvůrce
Profesionální internetový závislák • Herní nadšenec • Technologický tvůrce

Šest věcí, které jsem se naučil o gumovém posouvání v iOS Safari

Abych vyřešil problém se posouváním v Safari na iOS, byl jsem nucen vytvořit si svou vlastní jednoduchou testovací stránku!
Tuto stránku pro vaše pohodlí přeložili z angličtiny moji vysoce motivovaní stážisté v oblasti umělé inteligence. Stále se učí, takže se mohlo stát, že se vyskytnou nějaké chyby. Nejpřesnější informace naleznete v anglické verzi.
Domov Blog Šest věcí, které jsem se naučil o gumovém posouvání v iOS Safari

Vezměte prosím na vědomí, že tento blogový příspěvek byl publikován v červnu 2015, takže v závislosti na době, kdy jej čtete, mohou být některé části zastaralé. Bohužel nemohu tyto příspěvky vždy udržovat plně aktuální, aby informace zůstaly přesné.

Abych vyřešil nedávný problém se scrollováním v Safari na iOS, byl jsem nucen vytvořit vlastní jednoduchou testovací stránku a poté využít všechny informace a kombinace, které jsem našel na internetu, abych se pokusil problém vyřešit.

Níže je stručný přehled toho, co jsem během tohoto procesu zjistil.

Moje testovací stránka

Moje testovací stránka byla poměrně jednoduchá. Skládala se z ukázkových dat ve statickém divu, který měl představovat „stránku“, a z fixně umístěného divu představujícího překryté „menu“ nad stránkou, takto to vypadá.

Snímek obrazovky otevřeného HTML bočního menu v iOS Safari

Celý zdrojový kód této stránky najdete na konci tohoto blogového příspěvku.

Pochopení výchozího chování

První věc, kterou jsem udělal, bylo zjistit výchozí chování Safari na iOS. Nejvýraznějším zjištěním bylo, že když jste se posunuli až na samotný konec nabídky, tělo stránky vykazovalo "rubber-band efekt" – pevně zabudovaná funkce v Safari.

animovaný snímek obrazovky, který ukazuje problém s efektem pružení při posouvání na spodní části stránky v iOS Safari

To samé se stalo i při rolování až na úplný horní konec nabídky.

animovaný snímek obrazovky zobrazující problémový efekt gumové pružiny v iOS Safari, v horní části stránky

Nicméně první problém, který jsem si všiml, byl ten, že pokud neustále rolujete až na samotný vrchol nebo spodní konec, Safari začne vykazovat artefakty při vykreslování jak na pozadí stránky, tak v nabídce.

Nevím proč, ale mám podezření, že to souvisí s funkcí elastického efektu.

animovaný snímek obrazovky zobrazující závadu v iOS Safari ve spodní části stránky

Chápání toho, co dělá CSS pravidlo "-webkit-overflow-scrolling"

Dále jsem na menu aplikoval pravidlo CSS -webkit-overflow-scrolling, které umožňuje plynulé posouvání s momentumem.

Jak je vidět na níže uvedeném obrázku, posouvání pokračuje i po přejetí prstem.

ukázka problému s rolováním založeným na setrvačnosti v iOS Safari

Ale při scrollování až na úplný vrchol nebo dolní konec stránky se objeví i efekt pružení, jak je níže uvedeno.

předvádí problém se setrvačním posouváním na iOS Safari s efektem gumového pásu

Uživatel musí počkat, než skončí efekt gumového pásu

Během testování jsem si také všiml, že zatímco probíhá efekt gumového pásku, uživatel nemůže přepnout fokus na jiný prvek, dokud se animace plně nedokončí.

V níže uvedeném příkladu nejprve posunu pozadí stránky a poté rychle zkusím posouvat menu, ale nakonec budu pokračovat v posouvání pozadí stránky.

ukazuje, že na iOS Safari je pozadí stránky posunuto

Nicméně, pokud počkám chvíli, až efekt skončí, mohu pak začít procházet nabídku.

předvádí, jak dlouho trvá dokončení efektu gumového pásu v iOS Safari

Jak zabránit posouvání pozadí stránky

Během testování jsem si také všiml, že zatímco probíhá elastický efekt, uživatel nemůže přepnout fokus na jiný prvek, dokud se animace zcela neukončí.

Na základě této odpovědi na Stack Overflow můžete zajistit, že prvky s disable-scrolling neprovedou výchozí akci posouvání, když dojde k vyvolání události 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(); } };

A pak aplikujte třídu disable-scrolling na div stránky:

<div class="page disable-scrolling">

Takhle to sice funguje, ale při důkladnějším testování se ukazuje, že pozadí stránky se občas ještě posune, když dosáhnete na úplný horní nebo spodní konec nabídky.

ukazuje, že pozadí se stále posouvá

Jak zabránit nadměrnému posouvání stránky na pozadí

Použitím tohoto opravného řešení je možné zabránit „overscrollování“. To znamená, že když je prvek posouván až na horní nebo dolní okraj, posouvání se nepřenáší do těla stránky.

Výsledkem je, že tělo stránky nelze posouvat, což také zabraňuje vzniku efektu odskoku.

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 dělá tento kousek JavaScriptu, je to, že zabraňuje prvku dostat se až na horní ani dolní okraj, a udržuje ho jen 1 pixel od těchto okrajů.

Pokud se posun nikdy nedostane na absolutní horní ani dolní okraj, nedojde k overscrollu.

ukázka, jak zabránit posuvu za okraje tím, že se nikdy nedostaneme na horní ani dolní okraj obsahu

Jak zabránit posouvání na pozadí stránky

Pokud chcete odstranit efekt elastického posouvání z nabídky – ať už z estetických důvodů, nebo protože, jak tomu bylo u mě, způsoboval další problémy s vykreslováním – jednoduše odstraňte pravidlo CSS -webkit-overflow-scrolling.

Avšak, jak je níže vidět, ztratíte i plynulost rolování.

úplná ukázka, jak zabránit gumovému táhnutí na iOS Safari

Celý zdrojový kód stránky

Zde je úplný zdrojový kód stránky.

<!-- 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>

Napsáno uživatelem Special Agent Squeaky. Poprvé publikováno 10. 6. 2015. Naposledy aktualizováno 10. 6. 2015.

📺 Podívejte se na nejnovější video od Squeakyho!

Jak přidat jednoduché titulky v reálném čase k vašemu živému vysílání