html
ios
bootstrap-modal
mobile-safari
ios11
Кеккеме
источник
источник
Ответы:
Я исправил проблему, добавив
position:fixed
в тело при открытии модального окна. Надеюсь, что это поможет вам.источник
width:100%
чтобы ограничить ширину корпуса шириной устройства. В некоторых случаях, в зависимости от существующей разметки, это может быть проблемой. Мне также нравится решение @gentleboy (ниже), чтобы не оштрафовать другие браузеры без проблем, потому что при установке тела в фиксированное значение тело прокручивается вверх, что несколько раздражает.position:fixed
подал заявку на основную часть заявки. Вместо этого я изменил егоposition:absolute
наhtml
элемент, и это устранило мою проблему. Спасибо, Джен!Лично
position: fixed
прокрутите вверх автоматически . Достаточно обидно!Чтобы избежать наказания за другие устройства и версии, я применяю это исправление только к соответствующим версиям iOS.
** ВЕРСИЯ 1 - Исправлены все модальные окна **
Для javascript / jQuery
$(document).ready(function() { // Detect ios 11_x_x affected // NEED TO BE UPDATED if new versions are affected var ua = navigator.userAgent, iOS = /iPad|iPhone|iPod/.test(ua), iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua); // ios 11 bug caret position if ( iOS && iOS11 ) { // Add CSS class to body $("body").addClass("iosBugFixCaret"); } });
Для CSS
/* Apply CSS to iOS affected versions only */ body.iosBugFixCaret.modal-open { position: fixed; width: 100%; }
** ВЕРСИЯ 2 - Только выбранные модальные окна **
Я изменил функцию, чтобы она запускалась только для выбранных модальных окон с классом
.inputModal
Только модальные окна с входами должны быть затронуты, чтобы избежать прокрутки вверх.
Для javascript / jQuery
$(document).ready(function() { // Detect ios 11_x_x affected // NEED TO BE UPDATED if new versions are affected (function iOS_CaretBug() { var ua = navigator.userAgent, scrollTopPosition, iOS = /iPad|iPhone|iPod/.test(ua), iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua); // ios 11 bug caret position if ( iOS && iOS11 ) { $(document.body).on('show.bs.modal', function(e) { if ( $(e.target).hasClass('inputModal') ) { // Get scroll position before moving top scrollTopPosition = $(document).scrollTop(); // Add CSS to body "position: fixed" $("body").addClass("iosBugFixCaret"); } }); $(document.body).on('hide.bs.modal', function(e) { if ( $(e.target).hasClass('inputModal') ) { // Remove CSS to body "position: fixed" $("body").removeClass("iosBugFixCaret"); //Go back to initial position in document $(document).scrollTop(scrollTopPosition); } }); } })(); });
Для CSS
/* Apply CSS to iOS affected versions only */ body.iosBugFixCaret.modal-open { position: fixed; width: 100%; }
Для HTML Добавьте класс inputModal в модальный
<div class="modal fade inputModal" tabindex="-1" role="dialog"> ... </div>
Nota bene Функция javascript теперь запускается автоматически
** ОБНОВЛЕНИЕ iOS 11.3 - ошибка исправлена 😃🎉 **
В iOS 11.3 ошибка исправлена. Нет необходимости тестировать
OS 11_
вiOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua);
Но будьте осторожны, поскольку iOS 11.2 все еще широко используется (по состоянию на апрель 2018 года). Увидеть
стат 1
стат 2
источник
iOS11 = /OS 11_(\d{1,2})(_{0,1})(\d{1,2})/.test(us);
ios11 = /OS 11_(\d{1,2})/.test(ua);
Эта проблема выходит за рамки Bootstrap и выходит за рамки Safari. Это ошибка полного отображения в iOS 11, которая встречается во всех браузерах. Приведенное выше исправление не устраняет эту проблему во всех случаях.
Подробнее об ошибке сообщается здесь:
https://medium.com/@eirik.luka/how-to-fix-the-ios-11-input-element-in-fixed-modals-bug-aaf66c7ba3f8
Предположительно они уже сообщили об этом Apple как об ошибке.
источник
Ошибка, спасибо за ее обнаружение. В противном случае я бы ударился айфоном или головой о стену.
Самое простое исправление (изменение 1 строки кода):
Просто добавьте следующий CSS в HTML или во внешний файл CSS.
<style type="text/css"> .modal-open { position: fixed; } </style>
Вот полный рабочий пример:
.modal-open { position: fixed; }
<link href="https://getbootstrap.com/docs/3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@getbootstrap">Open modal for @getbootstrap</button> ...more buttons... <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="exampleModalLabel">New message</h4> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="recipient-name" class="control-label">Recipient:</label> <input type="text" class="form-control" id="recipient-name"> </div> <div class="form-group"> <label for="message-text" class="control-label">Message:</label> <textarea class="form-control" id="message-text"></textarea> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Send message</button> </div> </div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="https://getbootstrap.com/docs/3.3/dist/js/bootstrap.min.js"></script>
Я отправил здесь проблему: https://github.com/twbs/bootstrap/issues/24059
источник
Самое простое / чистое решение:
body.modal-open { position: fixed; width: 100%; }
источник
Эта проблема больше не воспроизводится после обновления ваших устройств Apple до iOS 11.3.
источник
Добавить
position: fixed;
вbody
когда модальный открыт.$(document).ready(function($){ $("#myBtn").click(function(){ $("#myModal").modal("show"); }); $("#myModal").on('show.bs.modal', function () { $('body').addClass('body-fixed'); }); $("#myModal").on('hide.bs.modal', function () { $('body').removeClass('body-fixed'); }); });
.body-fixed { position: fixed; width: 100%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <button type="button" class="btn btn-info btn-lg" id="myBtn">Open Modal</button> <!-- Modal --> <div class="modal fade" id="myModal" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Form</h4> </div> <div class="modal-body"> <div class="form-group"> <label class="control-label">Input #1</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #2</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #3</label> <input type="text" class="form-control"> </div> <div class="form-group"> <label class="control-label">Input #4</label> <input type="text" class="form-control"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> </div> </div> </div>
источник
Эти решения, использующие
position: fixed
и корректирующие положение на основе,scrollTop
работают очень хорошо, но у некоторых людей (включая меня) возникла другая проблема: курсор / курсор на клавиатуре не отображаются, когда вводы сфокусированы.Я заметил, что каретка / курсор работают только тогда, когда мы НЕ используем
position: fixed
тело. Так после попытки несколько вещей, я отказался от использования этого подхода и решил использоватьposition: relative
наbody
и использование ,scrollTop
чтобы исправить верхнее положение модального в вместо этого.Смотрите код ниже:
var iosScrollPosition = 0; function isIOS() { // use any implementation to return true if device is iOS } function initModalFixIOS() { if (isIOS()) { // Bootstrap's fade animation does not work with this approach // iOS users won't benefit from animation but everything else should work jQuery('#myModal').removeClass('fade'); } } function onShowModalFixIOS() { if (isIOS()) { iosScrollPosition = jQuery(window).scrollTop(); jQuery('body').css({ 'position': 'relative', // body is now relative 'top': 0 }); jQuery('#myModal').css({ 'position': 'absolute', // modal is now absolute 'height': '100%', 'top': iosScrollPosition // modal position correction }); jQuery('html, body').css('overflow', 'hidden'); // prevent page scroll } } function onHideModalFixIOS() { // Restore everything if (isIOS()) { jQuery('body').css({ 'position': '', 'top': '' }); jQuery('html, body').scrollTop(iosScrollPosition); jQuery('html, body').css('overflow', ''); } } jQuery(document).ready(function() { initModalFixIOS(); jQuery('#myModal') .on('show.bs.modal', onShowModalFixIOS) .on('hide.bs.modal', onHideModalFixIOS); });
источник
Как уже упоминалось ранее: установка
style.position
property
изbody
кfixed
РешаетiOS cursor misplacement
проблемы.Однако этот выигрыш достигается за счет принудительной прокрутки к верхней части страницы.
К счастью, эту новую
UX
проблему можно решить без особых затрат, используяHTMLElement.style
иwindow.scrollTo()
.Основная суть состоит в том, чтобы противодействовать
scroll to top
, манипулируяbody
элементомstyle.top
whenmounting
. Это делается с использованиемYOffset
значения, полученногоygap
переменной.Оттуда просто нужно сбросить
body's
style.top
до0
и переформатировать представление пользователя, используяwindow.scrollTo(0, ygap)
whendismounting
.См. Практический пример ниже.
// Global Variables (Manage Globally In Scope). const body = document.querySelector('body') // Body. let ygap = 0 // Y Offset. // On Mount (Call When Mounting). const onModalMount = () => { // Y Gap. ygap = window.pageYOffset || document.documentElement.scrollTop // Fix Body. body.style.position = 'fixed' // Apply Y Offset To Body Top. body.style.top = `${-ygap}px` } // On Dismount (Call When Dismounting). const onModalDismount = () => { // Unfix Body. body.style.position = 'relative' // Reset Top Offset. body.style.top = '0' // Reset Scroll. window.scrollTo(0, ygap) }
источник
functions
когдаmounting
иdismounting
. Спасибо.Если кто-то ищет исправление в vanilla js, которое работает на IOS> 11.2 и не требует дополнительного CSS:
(function() { if (!/(iPhone|iPad|iPod).*(OS 11_[0-2]_[0-5])/.test(navigator.userAgent)) return document.addEventListener('focusin', function(e) { if (!e.target.tagName == 'INPUT' && !e.target.tagName != 'TEXTAREA') return var container = getFixedContainer(e.target) if (!container) return var org_styles = {}; ['position', 'top', 'height'].forEach(function(key) { org_styles[key] = container.style[key] }) toAbsolute(container) e.target.addEventListener('blur', function(v) { restoreStyles(container, org_styles) v.target.removeEventListener(v.type, arguments.callee) }) }) function toAbsolute(modal) { var rect = modal.getBoundingClientRect() modal.style.position = 'absolute' modal.style.top = (document.body.scrollTop + rect.y) + 'px' modal.style.height = (rect.height) + 'px' } function restoreStyles(modal, styles) { for (var key in styles) { modal.style[key] = styles[key] } } function getFixedContainer(elem) { for (; elem && elem !== document; elem = elem.parentNode) { if (window.getComputedStyle(elem).getPropertyValue('position') === 'fixed') return elem } return null } })()
Что это значит:
focusin
события на страницеinput
или,textarea
и содержится в элементе сfixed
положением, измените положение контейнера наabsolute
при этомscrollTop
и исходные размеры контейнеров.fixed
.источник
Это решение сработало для меня, и оно хорошо работает во всех браузерах на iOS.
.safari-nav-force{ /* Allows content to fill the viewport and go beyond the bottom */ height: 100%; overflow-y: scroll; /* To smooth any scrolling behavior */ -webkit-overflow-scrolling: touch; }
JavsScript
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; $('.modal').on('shown.bs.modal', function () { if (iOS && $('.modal').hasClass('in')){ $('html,body').addClass('safari-nav-force'); } }); $('.modal').on('hidden.bs.modal', function () { if (iOS && !$('.modal').hasClass('in')){ $('html,body').removeClass('safari-nav-force'); } });
источник
Вы пробовали viewport-fit = cover для мета-окна просмотра.
Посмотрите на это: https://ayogo.com/blog/ios11-viewport/
источник
Переопределите модальный CSS и измените его
position
сfixed
наabsolute
.modal { position: absolute !important; }
источник
добавить в #modal position: absolute - исправить будущие проблемы, связанные с положением: fixed
источник