Статьи

Проблемы с фиксированной позицией и прокруткой на iOS

Говорят, что с выпуском iOS 5 в MobileSafari поддерживается фиксированное расположение.

Слово « поддержано» нужно воспринимать с небольшим количеством соли, потому что есть все виды вопросов, которые я собираюсь показать вам в следующем посте.

Обратите внимание, что во время бета-версии iOS 5 я исправлял ошибки для ряда из них — но бог знает, как работает Radar Apple, поэтому я не знаю номеров проблем.

Обновление: я добавил «прокрутка == неиспользуемая позиция: фиксированный элемент» на основе того, что Кори Дастон указывает на
больше ошибок с фиксированной позицией.

позиция: фиксированная, кого это волнует?

Я мог бы утверждать, что фиксированное позиционирование не имеет значения или действительно не требуется в хорошем приложении. Однако я заметил, что растет число приложений для iOS, которые на самом деле представляют собой просто набор веб-представлений (mini-MobileSafaris) с панелями инструментов с фиксированным положением, как это видно в собственном приложении Apple AppStore, родном приложении Facebook и Instagram ниже:

AppStore через @devongovett , Facebook через @ 9eggs

вопросы

Я создал несколько примеров страниц, которые вы можете просмотреть сами, которые используются в следующих видео.

скачкообразные

Если вы добавите обычным способом, как на «настольном» сайте, вы увидите некоторую степень дрожания при прокрутке страницы.position:fixed

Обратите внимание, что это симулятор, но я также запечатлел настоящий iPhone (используя Reflection), демонстрирующий то же поведение.

Используемая страница была: jsbin.com/3/ixewok/6/ ( редактировать )

Нет обновленных значений при прокрутке

Зритель с острыми глазами мог заметить некоторые значения, изменяющиеся в видео. Я отслеживаю и (и другое значение, которое мы рассмотрим позже). Вы заметите, что значения не изменятся, пока прокрутка не закончится.window.scrollTopwindow.pageYOffset

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

Положение дрейфа

Если страница вообще увеличена, что вы можете получить в iOS, когда пользователь поворачивается от портрета до пейзажа, когда пользователь прокручивает в любом масштабе, превышающем 1 (т. Е. Масштабируется), элемент с фиксированным положением смещается вверх (я видел этот дрейф) полностью вне поля зрения ранее на других сайтах)

Используемая страница была: jsbin.com/3/ixewok/6/ ( редактировать )

Фокус прыжки

Если внутри элемента с фиксированным положением есть фокусируемый элемент, то есть элемент ввода, это может привести к тому, что весь фиксированный элемент сместится с места. Это произойдет, только если пользователь прокрутил какую-либо сумму (но если вы используете, вы ожидаете именно такого рода использования).position:fixed

Используемая страница была: jsbin.com/3/ixewok/8/ ( редактировать )

Прокрутка == неиспользуемая позиция: фиксированный элемент

Кори Датсон отметил, что есть еще одна проблема с фиксированной позицией. Хотя в его примере показана прокрутка с использованием JavaScript, основная проблема заключается в следующем: если страница перемещается программно (т. Е. Пользователь не вызвал прокрутку), элементы внутри элемента fix недоступны.

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

Используемая страница была: jsbin.com/3/ixewok/13/ ( редактировать )

У меня пока нет исправления, и я подозреваю, что это основная проблема рисования в MobileSafari — но я буду продолжать играть, чтобы увидеть, есть ли что-то, что можно сделать.

Исправление дрожания

С iOS 5 также поставляется MobileSafari . Это на самом деле предназначено для встроенных блоков контента на странице (я имею в виду встроенный по отношению к документу).-webkit-overflow-scrolling: touch

Если изменить CSS в моем предыдущем примере, и установить предел моих html, bodyи блок контента на 100%, а затем применить скроллинг сенсорного свойства содержанию, скачкообразные уходит. Однако одно это не исправляет судьбу.

Казалось бы, хитрость заключается в следующем: убедитесь, что ваш элемент фиксированной позиции не находится на «движущемся холсте». Этот пример имеет фиксированный элемент над элементом прокрутки, но не внутри него.

Поэтому, когда я попытался применить эту технику к bodyэлементу, дрожание все еще было видно, так как фиксированный элемент находился внутри элемента прокрутки.

Я также захватил это на реальном устройстве тоже.

Используемая страница была: jsbin.com/3/ixewok/10/ ( редактировать )

Получение позиции прокрутки для обновления

Опять же, эти острые глаза, возможно, заметили, что значения снова движутся. Обратите внимание, что, поскольку я изменил CSS, тело больше не прокручивается, поэтому значения 0 слева и справа равны и соответственно. Поскольку окно не прокручивается, блок содержимого переполнен, значения не изменятся.window.scrollTopwindow.pageYOffset

Тем не менее, значение меняется — но не по умолчанию.content.scrollX

Во-первых, вы должны прикрепить любой обработчик события касания, чтобы обновить это значение, когда пользователь прокручивает (или фактически касается), поэтому в JavaScript я могу добавить:

content.ontouchstart = function () {};

Событие касания будет работать с началом, концом и перемещением, и ему просто нужно установить значение (обратите внимание, что я не проверял, просто установив его true— это тоже может сработать!).

Тем не менее, это все еще не идеально. Из видео выше вы увидите, что оно только обновляется, пока я прикасаюсь . Как только я отпускаю прокрутку во время прокрутки, импульс заставляет страницу продолжать прокручиваться, но значение не обновляется.

Я еще не выяснил, возможно ли вообще зафиксировать это значение. ::вздох::

Чтобы заключить / TL; DR

Не используйте внутри прокручиваемого элемента, это дурно и выглядит мусором (я видел намного хуже, чем дрожание, показанное в видео). Используйте и, если вам нужны значения прокрутки, убедитесь, что вы подключили сенсорный обработчик к этому элементу прокрутки.position:fixed-webkit-overflow-scrolling: touch

В то же время: сделайте так, чтобы это работало и в других мобильных браузерах — не только для Apple. Это огромная головная боль, что Apple наполовину исправила проблему и сделала это

типичным для Microsoft
способом.
position:fixed