Професионален интернет маниак • Гейм ентусиаст • Тех ентусиаст и създател
Професионален интернет маниак • Гейм ентусиаст • Тех ентусиаст и създател

Шест неща, които научих за еластичното превъртане в iOS Safari

За да оправя проблема със скролването в Safari на iOS, бях принуден да създам собствена проста тестова страница!
Тази страница е преведена от английски език от моите силно мотивирани стажанти по изкуствен интелект за ваше удобство. Те все още се учат, така че е възможно да са допуснати някои грешки. За най-точна информация, моля, вижте английската версия.
Дом Блог Шест неща, които научих за еластичното превъртане в iOS Safari

Моля, имай предвид, че тази публикация е от юни 2015 г. и може част от информацията вече да е остаряла. Ще я актуализирам, когато имам време.

За да оправя наскоро възникналия проблем със скролването в Safari на iOS, принудих се да създам собствена проста тестова страница и след това да използвам цялата налична информация и различните комбинации, които успях да намеря в интернет, за да опитам да разреша проблема.

По-долу е кратък преглед на това, което открих по време на този процес.

Моята тестова страница

Моята тестова страница беше доста проста. Тя се състоеше от примерни данни в статичен div, за да представлява «страницата», заедно с фиксиран div, който представлява надслойеното «меню» над страницата, както е показано.

Скриншот на отворено HTML странично меню в iOS Safari

Пълният изходен код на страницата можете да намерите в долната част на този блог пост.

Разбиране на поведението по подразбиране

Първото нещо, което направих, беше да се опитам да разбера какво е стандартното поведение на Safari на iOS. Най-забележителното наблюдение беше, че когато превъртите докрай менюто, тялото на страницата проявява ефекта на гумения ластик — заложена функционалност в Safari.

анимиран скрийншот на проблемния еластичен ефект при превъртане в iOS Safari в долната част на страницата

Същото се случи и когато превъртах до най-горната част на менюто.

анимиран скрийншот на проблематичния еластичен ефект в iOS Safari в горната част на страницата

Обаче първият проблем, който забелязах, беше, че ако продължавате да превъртате до върха или долната част на страницата, Safari започва да показва графични артефакти както във фоновата страница, така и в менюто.

Не съм сигурен защо, но подозирам, че има нещо общо с ефекта на ластика.

анимиран скрийншот на проблемите с 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">

По принцип това работи, но по-обстойното тестване показва, че фонова страница все още понякога може да се превърта, когато достигнете най-горната или най-долната част на менюто.

показва, че фоновото съдържание все още се скролва

Как да предотвратим прекомерното превъртане към фоновата страница.

Като приложите тази поправка, става възможно да се избегне „overscrolling“. Това означава, че когато даден елемент е превъртан до най-горния или най-долния му край, превъртането не продължава в тялото на страницата.

В резултат на това страницата не може да се превърта, което също предотвратява появата на ефекта на гумения ластик.

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 пиксел разстояние.

Ако превъртането никога не достига абсолютния горен край или абсолютния долен край, overscrolling не може да се случи.

демо за предотвратяване на прекалено превъртане — никога не достигате най-горната или най-долната точка

Как да предотвратим превъртането към фоновата страница

Ако искате да премахнете ефекта на опъване от менюто - било заради естетика или защото, както при мен, той предизвиква допълнителни проблеми с рендирането - просто премахнете CSS правилото -webkit-overflow-scrolling.

Въпреки това, както можете да видите по-долу, губите и инерцията на плавното превъртане.

пълен демонстрационен пример за предотвратяване на rubberbanding в 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. Първо публикувано на 10.06.2015 г. Последна актуализация на 10.06.2015 г.

📺 Гледайте най-новото видео на Squeaky!

Как да добавите субтитри в реално време към вашия стрийм на живо