Професійний інтернет-залежний • Ігровий ентузіаст • Технічний творець
Професійний інтернет-залежний • Ігровий ентузіаст • Технічний творець

Шість речей, які я дізнався про гумову прокрутку у iOS Safari

Щоб виправити проблему зі скролінгом у Safari на iOS, мені довелося створити власну просту тестову сторінку!
Цю сторінку було перекладено з англійської мови моїми високо мотивованими стажерами зі штучного інтелекту для вашої зручності. Вони все ще навчаються, тому могли бути допущені деякі помилки. Для отримання найточнішої інформації, будь ласка, зверніться до англійської версії.
Дім Блог Шість речей, які я дізнався про гумову прокрутку у iOS Safari

Зверніть увагу, що цей допис у блозі було опубліковано в червні 2015 року, тому залежно від того, коли ви його читаєте, деякі його частини можуть бути застарілими. На жаль, я не завжди можу повністю оновлювати ці дописи, щоб забезпечити точність інформації.

Щоб виправити нещодавню проблему з прокручуванням у Safari на iOS, мені довелося створити власну просту тестову сторінку, а потім застосувати всю інформацію та різноманітні комбінації, які я міг знайти в Інтернеті, щоб спробувати вирішити проблему.

Нижче наведено стислий огляд того, що мені вдалося з'ясувати під час цього процесу.

Моя тестова сторінка

Моя тестова сторінка була досить простою. Вона складалася з тестових даних у статичному div-елементі, щоб уявити «сторінку», разом із фіксованим div-елементом, який зображає накладене «меню» над сторінкою, ось так.

Знімок екрана відкритого HTML-бічного меню у Safari на iOS

Повний вихідний код цієї сторінки можна знайти внизу цього допису в блозі.

Розуміння поведінки за замовчуванням

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

анімаційний скріншот проблемного ефекту пружного відскоку (rubber band) у Safari на iOS, який з'являється внизу сторінки

Так само сталося, коли прокручували до самого верху меню.

анімований скріншот проблемного ефекту пружного відскоку в iOS Safari у верхній частині сторінки

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

Я не зовсім розумію, чому так, але думаю, що це має щось спільне з функцією еластичної прокрутки.

анімаційний скріншот проблеми з глюками в Safari на iOS у нижній частині сторінки

Розуміння того, як працює CSS-правило «-webkit-overflow-scrolling»

Наступним кроком стало застосування правила CSS -webkit-overflow-scrolling до меню, що забезпечує інерційне прокручування.

Як показано на зображенні нижче, прокручування продовжується навіть після того, як я провів пальцем.

демонструючи проблему інерційного прокручування у Safari на iOS

До того ж під час прокручування до самого верхнього або нижнього краю з'являється ефект гумової стрічки, як показано нижче.

Показує проблему інерційної прокрутки в iOS Safari з ефектом гумки.

Please wait for the rubber-band effect to finish.

Під час тестування я також помітив, що під час виконання ефекту відскоку користувач не може переключити фокус на інший елемент, доки анімація повністю не завершиться.

У наведеному нижче прикладі спочатку прокручую фонову сторінку, а потім швидко намагаюся прокрутити меню, але в підсумку продовжую прокручувати саме фонову сторінку.

показує, що фонова сторінка прокручена у Safari на iOS

Однак, якщо я трохи зачекаю, поки ефект закінчиться, зможу почати прокручувати меню.

показує очікування завершення ефекту пружного відскоку на 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(); } };

І потім застосуйте до елемента div сторінки клас disable-scrolling:

<div class="page disable-scrolling">

Цей підхід працює частково, але більш ґрунтовне тестування показує, що фонова сторінка все ще іноді прокручується, коли ви досягаєте самого верху або дна меню.

показує, що фон все ще прокручується

Як запобігти надмірному прокручуванню до фонової сторінки

За допомогою цього виправлення fix, можна запобігати «оверскролінгу». Це означає, що коли елемент прокручується до самого верху або низу, прокручування не переходить далі до тіла документа.

У результаті сторінка не прокручується, що також запобігає виникненню ефекту пружного відскоку.

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 запобігає тому, щоб елемент дійшов до самого верху або самого низу, утримуючи його на відстані всього одного пікселя.

Якщо положення прокрутки ніколи не досягає абсолютної верхньої чи нижньої межі, перевищення прокрутки неможливе.

демонстрація запобігання перепрокручуванню: прокрутка ніколи не доходить до самого верху або самого низу

Як запобігти перепрокручуванню до фонової сторінки

Якщо хочете прибрати ефект гумки з меню — або з естетичних причин, або тому, що, як у моєму випадку, він викликав додаткові проблеми з відображенням, просто видаліть CSS-правило -webkit-overflow-scrolling.

Однак, як видно нижче, ви також втрачаєте плавність прокручування.

повна демонстрація запобігання ефекту відскоку в 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 червня 2015 р. Останнє оновлення 10 червня 2015 р.

📺 Перегляньте останнє відео від Squeaky!

Як додати прості субтитри в режимі реального часу до вашого прямого ефіру