Прокрутка содержимого в фиксированном положении div на мобильном Safari внезапно останавливается - и начинает прокрутку самого контейнера

У меня есть контейнер с position:fixed с прокруткой содержимого внутри. Я показываю это как функцию чата на мобильных устройствах, но на мобильном Safari содержимое прокрутки внутри контейнера position:fixed перестает прокручиваться и начинает прокручивать сам контейнер.

Откройте эту ссылку на мобильном Safari, чтобы увидеть эффект: http://jsbin.com/ruyito

Редактируемый пример здесь: http://jsbin.com/ruyito/edit?html,css,output

Вопрос: Почему мой контейнер div начинает внезапно прокручивать свою позицию и останавливать прокрутку содержимого? (В Chrome на Android он работает без проблем)

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

Ответы

Ответ 1

Я сталкивался с этой проблемой несколько раз, пытаясь использовать использование overflow: scroll div в iOS Safari.

Я понимаю, что это связано с прокруткой/эластичной анимацией прокрутки . Кажется, что происходит:

  • Когда определенный контейнер (т.е. окно или ваш прокручиваемый div) запускает эти анимации, события блокируются в этом контейнере.
  • Когда контейнер overflow: scroll попадает в верхнюю/нижнюю часть его высоты прокрутки, он начинает прокрутку родительского контейнера - это также имеет место в Chrome.

В вашем примере вы можете заметить, что когда прокрутка перестает работать, не касаясь экрана в течение небольшого промежутка времени (скажем, 500 мс?), тогда попытка прокрутки снова работает.

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

У меня был некоторый успех в прошлом, не распространяя события касания от моего контейнера прокрутки до документа:

$('.chat-container-mobile').on({
    'touchstart': _onTouchStart,
    'touchmove': _onTouchMove,
    'touchend': _onTouchEnd
});

function _onTouchStart(e) {

    e.stopPropagation();
}

function _onTouchMove(e) {

    e.stopPropagation();
}

function _onTouchEnd(e) {

    e.stopPropagation();
}

Примечание. Это не будет проблемой во многих ситуациях, так как вам часто нужно сохранять поведение по умолчанию в окне. В этом случае, однако, у вас, похоже, есть фиксированный макет, который не требует поведения прокрутки по умолчанию. Кроме того, вы, скорее всего, по-прежнему увидите тот же результат, если попытаетесь прокрутить, коснувшись верхней панели "Групповой чат" или нижней панели "Тип сообщения", а затем быстро попробуйте прокрутить в своем контейнере.

Вы также можете попробовать использовать e.preventDefault в $(document) для этих событий касания. Это предотвращает, чтобы окно реагировало на эти пользовательские входы в первую очередь, опять же, хотя это может вызвать много других проблем, если вам нужно сохранить настройки браузера по умолчанию.

Также попытайтесь локализовать эти привязки только в ситуациях, когда это проблема. Поэтому проверьте для iOS и Safari перед привязкой к событиям.

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

Удачи!

Ответ 2

Я открыл ссылку (http://jsbin.com/ruyito) iPhone 6 - Safari, и все выглядит отлично. Содержимое прокручивается, как ожидалось. Я много раз пробовал прокрутку вверх и вниз, но ничего не происходило.

В какой версии это происходит? Я не мог ничего сказать без опыта, но думаю, что это может быть проблема с виртуальным прокруткой.

Вы можете отключить это, добавив это.

.chat-container-mobile {
    -moz-transition: none;
    -webkit-transition: none;
    -o-transition: color 0 ease-in;
    transition: none;
}

Ответ 3

Я не знаю, что это за сделка. Возможно, сафари замерзает при его быстром перемещении, поскольку он по-прежнему технически перемещает контейнер так, как он должен по определению инструментов инспектора, просто не изображает его на экране.

Одна вещь, которую вы могли бы попробовать, что я сделал в инструментах инспектора, и, похоже, решает проблему, - это обратное проектирование того, что у вас есть. Попробуйте изменить этот код на свой код. обратите внимание на позиционирование/высоту/дополнение на вашем .chat-container-mobile и z-index/bottom/positioning на других двух элементах.

<style>
.chat-container-mobile {
position: fixed;
background-color: #EBEBEB;
padding: 15px;
display: block;
margin: 0;
top: 0px;
color: #444444;
overflow: scroll;
-webkit-overflow-scrolling: touch;
height: calc(100vh - 50px);
padding: 75px 15px 125px;
}
.chat-mobile-header {
position: fixed;
z-index: 10;
width: 100%;
background-color: white;
color: #444444;
text-transform: uppercase;
letter-spacing: 0.04em;
font-size: 15px;
font-weight: 500;
text-align: center;
top: 0;
margin: 0;
padding: 17px 0;
border-bottom: 1px solid rgba(68, 68, 68, 0.2);
}
.chat-field-mobile {
position: fixed;
width: 100%;
z-index: 10;
bottom: 0;
margin: 0px;
padding: 12px 12px 10px 10px;
background-color: #EBEBEB;
border-top: 1px solid rgba(68, 68, 68, 0.1);
}
</style>

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

Надеюсь, что это поможет приятелю!

Ответ 4

Просто попробуйте добавить bottom:0 в .chat-container-mobile { bottom:0 }