Профессиональный интернет-зависимый • Любитель игр • Создатель технологий
Профессиональный интернет-зависимый • Любитель игр • Создатель технологий

Шесть вещей, которые я узнал о прокрутке с эффектом резинки в 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">

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

демонстрируя, что фон всё ещё прокручивается

Как предотвратить лишнюю прокрутку фоновой страницы

Применив это исправление, можно предотвратить «перепрокрутку». Это означает, что когда элемент прокручивается до самого верха или низа, прокрутка не продолжится в тело документа.

В результате прокрутка тела страницы отключена, что также исключает возникновение эффекта резиновой прокрутки.

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 г.

📺 Посмотрите последнее видео от Сквики!

Как добавить простые субтитры в реальном времени к вашему прямому эфиру.