iOS Safari / Chrome-нежелательная прокрутка при фокусировке ввода внутри модального
протестировано в Safari и Chrome-тот же результат, поэтому я думаю, что это проблема iOS.
Это происходит, только если есть вход внутри модального, и я нажимаю этот вход. В тот же момент, что вход получил фокус и родную клавиатуру iOS становятся видимыми.
страница ниже модальной в тот же момент автоматически прокручивается до 50% ее высоты. Это поведение совершенно нежелательно, и я понятия не имею, как предотвратить эту iOS по умолчанию "особенность."
демо:
6 ответов
просто добавив ответ здесь, если люди наткнутся на этот вопрос (а не ваш другой вопрос, который имеет отличную демонстрацию, чтобы проиллюстрировать эту проблему)
мы сталкиваемся с аналогичной проблемой на работе. Как вы упомянули, смещение всегда составляет ~50% высоты страницы, что происходит независимо от того, где находится ваше начальное смещение.
в прошлом, когда я наблюдал подобные "прыжки" с более ранними версиями iOS( хотя, гораздо менее драматичные прыжки), я обычно работали вокруг этого, применяя position: fixed
(или relative
) к body
(позволяет overflow: hidden
для правильной работы).
однако это имеет автоматическое последствие перехода пользователя обратно в верхнюю часть страницы, если они прокрутили вниз.
Итак, если вы открыты для решения этой проблемы с некоторыми JavaScript
, вот исправление / хак, который я бросил вместе:
// Tapping into swal events
onOpen: function () {
var offset = document.body.scrollTop;
document.body.style.top = (offset * -1) + 'px';
document.body.classList.add('modal--opened');
},
onClose: function () {
var offset = parseInt(document.body.style.top, 10);
document.body.classList.remove('modal--opened');
document.body.scrollTop = (offset * -1);
}
и как выглядит CSS:
.modal--opened {
position: fixed;
left: 0;
right: 0;
}
здесь вилка вашей демо-страницы (из вашего другого вопроса), чтобы проиллюстрировать:https://jpattishall.github.io/sweetalert2/ios-bug.html
и для тех, кто ищет более общее исправление, вы можете сделать что-то вроде следующего при открытии/закрытии модального:
function toggleModal() {
var offset;
if (document.body.classList.contains('modal--opened')) {
offset = parseInt(document.body.style.top, 10);
document.body.classList.remove('modal--opened');
document.body.scrollTop = (offset * -1);
} else {
offset = document.body.scrollTop;
document.body.style.top = (offset * -1) + 'px';
document.body.classList.add('modal--opened');
}
}
Edit: чтобы избежать "переключения / отключения" на рабочих столах, я бы предложил обнаружение функций / UA sniffing применить это только к мобильному safari.
поэтому я решил это и протестировал на своем Iphone 5, У меня нет Ipad для проверки.
Я отключить overflow:hidden
в моем решении вы можете добавить, если хотите отключить прокрутку все в одном для всех модалов.
Решение состоит в том, чтобы добавить в основном свойство height и position как к html, так и к элементу body.
html, body {
position:relative;
/*overflow:hidden;*/
height: 100%;
}
таким образом, только когда вы сосредоточитесь на входе, высоте и положении, я уже закодировал это решение из вашего РЕПО, я отправлю вам запрос на вытягивание. Я также добавил browsersync в в настройках залпом. Поэтому теперь его будет легко протестировать на любом устройстве.
Ура!
EDIT: другой способ, если выше решение не работает по какой-то причине. затем,
/*
* @summary touch handler; will remove touch ability
* @author yeomann
*/
function Touchyhandler(e) {
e.preventDefault();
}
и позже прагматично добавить и удалить сенсорный прослушиватель, как это
//to add
document.addEventListener('touchmove', Touchyhandler, false);
//to remove
document.removeEventListener('touchmove', Touchyhandler);
над решением js, протестированным на IOS 9.3.2, работает как шарм для меня]
чтобы остановить прокрутку страницы, как по оси x, так и по оси y, мы используем overflow: hidden;
атрибут в css.
Итак, если мы применим это к телу,
body {
overflow: hidden !important;
}
он должен работать правильно?
на самом деле, это на самом деле не работает, потому что вы только что отключили прокрутку x и y для всей страницы в течение всего времени.
чтобы обойти это, мы можем использовать TAD javascript для добавления класса в тело, когда модальный активен.
Сначала мы должны добавьте идентификатор к нашему телу,<body id="body">
это позволяет javascript распознавать тело.
во-вторых, мы должны добавить идентификатор к нашему модальному,<div id="modal">
, также позволяя javascript распознавать модальные.
<script type="text/javascript">
function modalActive() {
if (document.getElementById("modal").classList.contains("active")) {
document.getElementById("body").classList.add("modal-active");
} else {
getElementById("modal").classList.remove("active"));
getElementById("body").classList.remove("modal-active"));
}
}
</script>
для кнопки, которая запускает и закрывает модальный, мы должны добавить событие onclick,
<button onclick="modalActive()">Click Me!</button>
кроме того, мы должны добавить это в файл css.
body {
overflow: initial !important;
}
body.modal-active {
overflow: hidden !important;
}
и вот мы идем.
Я не уверен на 100%, но я могу представить следующее:
при появлении клавиатуры высота окна уменьшается, но значение scrollTop остается прежним, поэтому сайт переходит к этому значению. Вы можете добавить overflow:hidden
до body
когда модальный открыт. Это заблокирует прокрутку" за " модальным и, вероятно, решит вашу проблему.
Я также испытал эту проблему. Краткое объяснение заключается в том, что iOS Safari попытается автоматически прокрутить любой вход, на котором сосредоточен, и в этом конкретном случае сфокусированный элемент находится в фиксированном позиционированном элементе. Safari, похоже, борется с поиском элемента фиксированной позиции, когда он хочет центрировать элемент на экране, следовательно, прокрутка фона.
одним из возможных решений является добавление touchstart
прослушиватель событий в поле ввода и вычислить текущий положение оверлея, измените положение на абсолютное и обновите верхнее / левое положение, чтобы поместить оверлея туда, где он был на экране при фиксированном положении, и, наконец, добавьте новый blur
прослушиватель для сброса наложения обратно в фиксированное положение при выходе фокуса / размытия на входе. Это должно предотвратить прокрутку страницы. Я предлагаю использовать touchstart
потому что он должен вызвать перед focus
событие, при котором страница уже начнет прокрутку. Safari должен иметь возможность найдите и центрируйте абсолютное расположенное наложение, когда focus
событие срабатывает.
Я пробовал несколько вещей, которые работали для модальных входов на html-странице. Самым простым решением, которое сработало для меня, было добавление следующих стилей в тег тела, когда модальный открыт на странице.
position: fixed;
width: 100%;