Επαγγελματίας Εξαρτημένος στο Διαδίκτυο • Λάτρης των Παιχνιδιών • Δημιουργός Τεχνολογίας
Επαγγελματίας Εξαρτημένος στο Διαδίκτυο • Λάτρης των Παιχνιδιών • Δημιουργός Τεχνολογίας

Έξι πράγματα που έμαθα για την ελαστική κύλιση στο Safari του iOS

Για να διορθώσω ένα πρόβλημα κύλισης στο Safari σε iOS, αναγκάστηκα να δημιουργήσω τη δική μου απλή σελίδα δοκιμής!
Αυτή η σελίδα έχει μεταφραστεί από τα Αγγλικά από τους ιδιαίτερα δραστήριους ασκούμενούς μου στην Τεχνητή Νοημοσύνη για την καλύτερη εξυπηρέτησή σας. Μαθαίνουν ακόμα, επομένως ενδέχεται να έχουν γίνει κάποια λάθη. Για τις πιο ακριβείς πληροφορίες, ανατρέξτε στην αγγλική έκδοση.
Σπίτι Ιστολόγιο Έξι πράγματα που έμαθα για την ελαστική κύλιση στο Safari του iOS

Λάβετε υπόψη ότι αυτή η ανάρτηση ιστολογίου δημοσιεύτηκε τον Ιούνιο του 2015, επομένως, ανάλογα με το πότε την διαβάζετε, ορισμένα σημεία ενδέχεται να είναι παρωχημένα. Δυστυχώς, δεν μπορώ πάντα να διατηρώ αυτές τις αναρτήσεις πλήρως ενημερωμένες για να διασφαλίσω ότι οι πληροφορίες παραμένουν ακριβείς.

Για να διορθώσω ένα πρόσφατο πρόβλημα κύλισης στο Safari σε iOS, αναγκάστηκα να φτιάξω τη δική μου απλή σελίδα δοκιμών και στη συνέχεια να εφαρμόσω όλες τις πληροφορίες και τους συνδυασμούς που βρήκα στο διαδίκτυο, προκειμένου να προσπαθήσω να λύσω το ζήτημα.

Ακολουθεί μια σύντομη επισκόπηση όσων ανακάλυψα κατά τη διάρκεια αυτής της διαδικασίας.

Η σελίδα δοκιμών μου

Η σελίδα δοκιμών μου ήταν αρκετά βασική. Αποτελούταν από δοκιμαστικά δεδομένα σε ένα στατικό div που απεικόνιζε τη «σελίδα», μαζί με ένα σταθερό div που βρισκόταν πάνω από τη σελίδα και απεικόνιζε ένα επικαλυπτόμενο «μενού», όπως φαίνεται.

Ένα στιγμιότυπο ενός ανοιχτού πλευρικού μενού HTML στο Safari για iOS.

Ο πλήρης κώδικας πηγής της σελίδας βρίσκεται στο τέλος αυτού του άρθρου στο blog.

Κατανόηση της προεπιλεγμένης συμπεριφοράς

Το πρώτο πράγμα που έκανα ήταν να προσπαθήσω να καταλάβω τη βασική συμπεριφορά του Safari στο iOS. Η πιο αξιοσημείωτη παρατήρηση ήταν ότι όταν κύλιζες μέχρι το τέλος του μενού, το σώμα της σελίδας εμφάνιζε ένα «εφέ λάστιχου» — ένα χαρακτηριστικό που έχει προγραμματιστεί εξ αρχής στον Safari.

ένα κινούμενο στιγμιότυπο οθόνης του προβληματικού εφέ ελαστικού (rubber band) στο iOS Safari, στο κάτω μέρος της σελίδας

Το ίδιο συνέβη όταν κάνατε κύλιση μέχρι την κορυφή του μενού.

Ένα κινούμενο στιγμιότυπο οθόνης του προβληματικού εφέ ελαστικότητας στο iOS Safari στην κορυφή της σελίδας

Ωστόσο, το πρώτο πρόβλημα που παρατήρησα είναι ότι, εάν συνεχίσετε να κυλάτε προς την κορυφή ή προς το κάτω μέρος της σελίδας, το Safari αρχίζει να παρουσιάζει προβλήματα απεικόνισης τόσο στο φόντο της σελίδας όσο και στο μενού.

Δεν είμαι σίγουρος γιατί, αλλά υποπτεύομαι ότι έχει σχέση με το εφέ ελαστικού.

Ένα κινούμενο στιγμιότυπο οθόνης του προβλήματος με glitches στο iOS Safari στο κάτω μέρος της σελίδας

Κατανόηση του τι κάνει ο κανόνας CSS «-webkit-overflow-scrolling».

Το επόμενο βήμα που έκανα ήταν να εφαρμόσω τον κανόνα CSS -webkit-overflow-scrolling στο μενού, ο οποίος ενεργοποιεί την κύλιση με ορμή.

Όπως φαίνεται στην εικόνα παρακάτω, η κύλιση συνεχίζεται ακόμη και αφού σύρω το δάχτυλό μου.

παρουσιάζοντας το πρόβλημα κύλισης με ορμή στο iOS Safari

Αλλά προσθέτει επίσης ένα εφέ ελαστικής κίνησης όταν κάνετε κύλιση μέχρι την κορυφή ή το τέλος, όπως φαίνεται παρακάτω.

Εμφανίζοντας το πρόβλημα κύλισης με ορμή στο iOS Safari, με το εφέ λάστιχου

Ο χρήστης πρέπει να περιμένει μέχρι να ολοκληρωθεί το εφέ ανάκρουσης

Κατά τη διάρκεια των δοκιμών μου, παρατήρησα επίσης ότι ενώ βρίσκεται σε εξέλιξη το εφέ ελαστικού, ο χρήστης δεν μπορεί να μεταφέρει την εστίαση σε άλλο στοιχείο μέχρι να ολοκληρωθεί πλήρως η κίνηση.

Στο παράδειγμα που ακολουθεί, αρχικά κυλάω τη σελίδα στο φόντο και μετά προσπαθώ γρήγορα να κυλήσω το μενού, αλλά τελικά συνεχίζω να κυλάω τη σελίδα στο φόντο.

παρουσιάζοντας ότι η σελίδα φόντου έχει κύλιση αντί για το iOS Safari

Ωστόσο, αν περιμένω λίγο μέχρι να ολοκληρωθεί το εφέ, τότε μπορώ να αρχίσω να κυλίσω το μενού.

παρουσιάζοντας την αναμονή μέχρι την ολοκλήρωση του εφέ ελαστικής ανάκαμψης στο iOS Safari

Πώς να αποτρέψετε την κύλιση της σελίδας στο παρασκήνιο.

Κατά τη διάρκεια των δοκιμών μου, διαπίστωσα επίσης ότι καθώς το εφέ ελαστικής έκτασης βρίσκεται σε εξέλιξη, ο χρήστης δεν μπορεί να μεταβεί σε άλλο στοιχείο μέχρι να ολοκληρωθεί πλήρως η κίνηση.

Με βάση αυτήν την απάντηση από το Stack Overflow, μπορείτε να διασφαλίσετε ότι τα στοιχεία με το disable-scrolling δεν θα εκτελούν την προεπιλεγμένη ενέργεια κύλισης όταν ενεργοποιείται το γεγονός 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(); } };

Και στη συνέχεια εφαρμόστε την κλάση disable-scrolling στο div της σελίδας:

<div class="page disable-scrolling">

Κάπως λειτουργεί, αλλά οι πιο εκτεταμένες δοκιμές δείχνουν ότι η σελίδα υποβάθρου μπορεί ακόμη μερικές φορές να κυλίσει όταν φτάνετε στην κορυφή ή στην κάτω άκρη του μενού.

δείχνοντας ότι το φόντο συνεχίζει να κυλάει

Πώς να αποτρέψετε την κύλιση της σελίδας στο παρασκήνιο

Με την εφαρμογή αυτής της διόρθωση, καθίσταται δυνατή η αποτροπή της «υπερκύλισης». Αυτό σημαίνει ότι όταν ένα στοιχείο έχει μετακινηθεί μέχρι την απόλυτη κορυφή ή το κάτω άκρο του, η κύλιση δεν συνεχίζεται μέσα στο σώμα της σελίδας.

Ως αποτέλεσμα, εμποδίζεται η κύλιση της σελίδας, οπότε αποτρέπεται και το φαινόμενο της ελαστικής κίνησης (rubber-band).

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

Αυτό το απόσπασμα JavaScript αποτρέπει το στοιχείο από το να φτάσει ποτέ στην κορυφή ή στην κάτω άκρη, κρατώντας το μόλις 1 εικονοστοιχείο μακριά.

Αν η θέση κύλισης δεν φτάνει ποτέ στην απόλυτη κορυφή ή στο απόλυτο κάτω άκρο, η υπερκύλιση δεν μπορεί να συμβεί.

παράδειγμα αποτροπής υπερβολικής κύλισης, αποφεύγοντας να φτάνεις ποτέ στην αρχή ή στο τέλος της σελίδας

Πώς να αποτρέψετε το υπερβολικό κύλισμα προς τη σελίδα φόντου

Αν θέλετε να αφαιρέσετε το εφέ ελαστικής ανάδρασης από το μενού — είτε για αισθητικούς λόγους είτε, όπως στην περίπτωσή μου, επειδή προκάλεσε επιπλέον προβλήματα απόδοσης — απλώς αφαιρέστε τον κανόνα CSS -webkit-overflow-scrolling.

Ωστόσο, όπως φαίνεται παρακάτω, χάνετε επίσης τη δυναμική της ομαλής κύλισης.

Πλήρες παράδειγμα για την αποτροπή του rubber banding στο iOS Safari

Ολόκληρος κώδικας πηγής της σελίδας

Ο πλήρης κώδικας πηγής της σελίδας βρίσκεται παρακάτω.

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

Γράφτηκε από τον/την Special Agent Squeaky. Πρώτη δημοσίευση 2015-06-10. Τελευταία ενημέρωση 2015-06-10.

📺 Δες το τελευταίο βίντεο του Squeaky!

Πώς να προσθέσετε απλούς υπότιτλους πραγματικού χρόνου στη ζωντανή σας μετάδοση