Professionele internetverslaafde • Game-enthousiasteling • Tech-maker
Professionele internetverslaafde • Game-enthousiasteling • Tech-maker

Zes dingen die ik leerde over het rubberband-effect in iOS Safari

Om een scrollprobleem in Safari op iOS op te lossen, moest ik mijn eigen eenvoudige testpagina maken!
Deze pagina is voor uw gemak vertaald uit het Engels door mijn zeer gemotiveerde AI-stagiaires. Ze zijn nog in ontwikkeling, dus er kunnen een paar foutjes doorheen zijn geglipt. Raadpleeg de Engelse versie voor de meest accurate informatie.
Thuis Blog Zes dingen die ik leerde over het rubberband-effect in iOS Safari

Houd er rekening mee dat deze blogpost in juni 2015 is gepubliceerd. Afhankelijk van wanneer u hem leest, kunnen bepaalde delen dus verouderd zijn. Helaas kan ik deze berichten niet altijd volledig up-to-date houden om ervoor te zorgen dat de informatie accuraat blijft.

Om een recent scrollprobleem in Safari op iOS op te lossen, moest ik mijn eigen eenvoudige testpagina maken en vervolgens alle informatie en combinaties die ik op internet kon vinden toepassen om te proberen het probleem op te lossen.

Hieronder vindt u een beknopt overzicht van wat ik tijdens dit proces heb ontdekt.

Mijn testpagina

Mijn testpagina was vrij eenvoudig. Het bestond uit voorbeeldgegevens in een statische div om de 'pagina' voor te stellen, samen met een vaste div die een overlay-menu boven de pagina laat zien, zoals dit.

Een screenshot van een geopend HTML-zijmenu in iOS Safari

De volledige broncode van de pagina is onderaan dit blogbericht te vinden.

Het standaardgedrag begrijpen

Het eerste wat ik deed, was proberen het standaardgedrag van Safari op iOS te begrijpen. De meest opvallende waarneming was dat wanneer je helemaal naar de onderkant van het menu scrolt, de body van de pagina een rubberband-effect vertoonde — een vast ingebouwde eigenschap in Safari.

een geanimeerde schermafbeelding van het problematische rubberband-effect in iOS Safari aan de onderkant van de pagina

Hetzelfde gebeurde toen je naar de bovenkant van het menu scrollde.

een geanimeerde schermafbeelding van het problematische rubberband-effect in iOS Safari bovenaan de pagina

Het eerste probleem dat me opviel, was dat Safari weergaveproblemen begon te vertonen wanneer je voortdurend helemaal naar boven of helemaal naar beneden scrolt, in zowel de achtergrondpagina als het menu.

Ik weet niet zeker waarom, maar ik vermoed dat het te maken heeft met de rubberbandfunctie.

een geanimeerde schermafbeelding van het haperende iOS Safari-probleem onderaan de pagina

Begrijpen wat de CSS-regel '-webkit-overflow-scrolling' doet

Het volgende wat ik deed, was de -webkit-overflow-scrolling CSS-regel toe te passen op het menu, wat momentum-gebaseerd scrollen mogelijk maakt.

Zoals in de onderstaande afbeelding te zien is, blijft het scrollen doorgaan, zelfs nadat ik met mijn vinger over het scherm veeg.

het momentum-gebaseerde scrollprobleem op iOS Safari tonen

Maar het voegt ook een rubberband-gevoel toe wanneer je naar de allereerste positie bovenaan of onderaan scrolt, zoals hieronder weergegeven.

laat het momentumgebaseerde scrollprobleem zien op ios safari met het rubberband-effect

De gebruiker moet wachten totdat het rubberband-effect is afgelopen.

Tijdens mijn tests merkte ik ook op dat, terwijl het rubberband-effect gaande is, de gebruiker de focus niet naar een ander element kan verplaatsen totdat de animatie volledig is voltooid.

In het onderstaande voorbeeld scroll ik eerst de achtergrondpagina en probeer daarna snel het menu te scrollen, maar uiteindelijk blijf ik toch de achtergrondpagina scrollen.

Laat zien dat de achtergrondpagina op iOS Safari is gescrold

Echter, als ik even wacht tot het effect is afgelopen, kan ik daarna door het menu scrollen.

tonen hoe lang het duurt voordat het rubberband-effect in iOS Safari is voltooid

Hoe voorkom je dat de achtergrondpagina scrollt

Tijdens mijn tests merkte ik ook op dat het rubberband-effect gaande is en dat de gebruiker de focus niet naar een ander element kan verschuiven totdat de animatie volledig is afgelopen.

Gebaseerd op dit antwoord van Stack Overflow, kun je ervoor zorgen dat elementen met disable-scrolling niet hun standaard scrollactie uitvoeren wanneer het touchmove evenement wordt geactiveerd.

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(); } };

En pas vervolgens de klasse disable-scrolling toe op de pagina-div:

<div class="page disable-scrolling">

Dit werkt wel redelijk, maar bij uitgebreide tests blijkt dat de achtergrondpagina soms nog kan scrollen wanneer je de boven- of onderkant van het menu bereikt.

laat zien dat de achtergrond nog steeds aan het scrollen is

Hoe voorkom je overmatig scrollen naar de achtergrondpagina

Door deze fix toe te passen, wordt overscroll voorkomen. Dit betekent dat wanneer een element helemaal naar de top of de onderkant is gescrold, het scrollen niet verder gaat in de body.

Als gevolg hiervan kan de pagina niet meer scrollen, waardoor ook het rubberband-effect niet optreedt.

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"));

Wat deze JavaScript-snippet doet, is voorkomen dat het element ooit tegen de bovenkant of onderkant aankomt door het op slechts 1 pixel afstand te houden.

Als de scrollpositie nooit de absolute bovenkant of onderkant bereikt, kan overscrollen nooit plaatsvinden.

voorbeeld van het voorkomen van overscroll door nooit helemaal naar de bovenkant of helemaal naar de onderkant te gaan

Hoe voorkom je dat je naar de achtergrondpagina scrolt

Als je het rubberband-effect van het menu wilt verwijderen—hetzij om esthetische redenen, of omdat het, zoals in mijn geval, extra weergaveproblemen veroorzaakte—verwijder dan eenvoudig de CSS-regel -webkit-overflow-scrolling.

Maar zoals hieronder te zien is, verlies je ook de vloeiende scroll-ervaring.

volledige demo voor het voorkomen van rubberbanding op iOS Safari

Volledige broncode van de pagina

Hier is de volledige broncode van de pagina.

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

Geschreven door Special Agent Squeaky. Eerste publicatie 2015-06-10. Laatste update 2015-06-10.

📺 Bekijk de nieuwste video van Squeaky!

Hoe voeg je eenvoudige realtime ondertitels toe aan je livestream