IOS 11 Модифицированная текстовая область загрузки Safari вне курсора

С сафари iOS 11 входной курсор находится вне текстового поля ввода. Мы не поняли, почему у этого проблемы. Поскольку вы можете видеть, что мое сосредоточенное текстовое поле - это текстовый ввод электронной почты, но мой курсор находится за его пределами. Это происходит только с iOS 11 Safari

Проблема

Ответ 1

Я исправил проблему, добавив position:fixed к телу при открытии модального. Надеюсь, это поможет вам.

Ответ 2

Лично position: fixed прокрутите вверх автоматически. Довольно раздражает!

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

Для javascript/jQuery

$(document).ready(function() {

    // Detect ios 11_0_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_1|OS 11_0_2|OS 11_0_3|OS 11_1|OS 11_1_1|OS 11_1_2|OS 11_2|OS 11_2_1/.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%; }

UPDATE 1 Добавлена ​​версия ОС 11.1, так как ошибка все еще находится в этой версии

Ответ 3

Эта проблема выходит за рамки Bootstrap и помимо Safari. Это полная ошибка отображения в iOS 11, которая встречается во всех браузерах. Исправление выше не устраняет эту проблему во всех случаях.

Об этом подробно сообщается здесь:

https://medium.com/@eirik.luka/how-to-fix-the-ios-11-input-element-in-fixed-modals-bug-aaf66c7ba3f8

Предположительно, они уже сообщили об этом Apple в качестве ошибки.

Ответ 4

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

Самое простое исправление (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">&times;</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>

Ответ 5

Самое простое/чистое решение:

body.modal-open { position: fixed; width: 100%; }

Ответ 6

Добавьте 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">&times;</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>

Ответ 7

Если кто-то ищет исправление в 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
    }
})()

Что это такое:

  • Проверьте, включен ли браузер Safari в iOS 11.0.0 - 11.2.5
  • Прослушать любые события focusin на странице
  • Если сфокусированный элемент является input или textarea и содержится в элементе с позицией fixed, измените положение контейнера на absolute, а в отношении scrollTop и исходных размеров контейнеров.
  • При размытии восстановите позицию контейнера до fixed.

Ответ 9

Отменить модальный css и изменить его position от fixed до absolute

.modal {
position: absolute !important;
}

Ответ 10

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

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

JS

var scroll = $(document).scrollTop();
$("body").css("top", -scroll);
$("body").addClass("modal-open");
/* open modal */
[...]
$("body").css("top", "0");
$("body").removeClass("modal-open");
$(document).scrollTop(scroll);
/* remove modal */

CSS

body.modal-open {
    overflow: hidden;
    height: 100%;
    width: 100%;
    position: fixed;
}

Нет необходимости проверять устройства iOS, поскольку этот трюк должен исправить ошибку iOS и работать на всех устройствах.

Ответ 11

Проблема, как многие люди описали, связана с:

position:fixed

Теперь, если вы откроете модальный, вы будете брошены в заголовок страницы... Чтобы избежать этого, я использую это решение (рядом с @Will's).

Сначала убедитесь, что устройство iOS:

var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

Если устройство iOS - добавьте класс iOS-устройства в тело:

if (iOS) {
    $('body').addClass('iOS-device');
}

Сделать переменную для сохранения положения прокрутки:

var scrollPosition;

Теперь обнаруживаем событие show.bs.modal и устанавливаем верхнее свойство iOS-устройства для отрицательного scrollPosition:

$('.modal').on('show.bs.modal', function() {
    scrollPosition = $(window).scrollTop();
    $('.iOS-device').css('top', -scrollPosition);
});

Затем определите событие hide.bs.modal, удалите класс modal-open, reset верхнее значение iOS-устройства и прокрутите документ до момента, когда он был до того, как модальный был открыт:

$('.modal').on('hide.bs.modal', function() {
    $('.iOS-device').removeClass('modal-open');
    $('.iOS-device').css('top', 0);
    $(document).scrollTop(scrollPosition);    
});

И полный код:

( function() {

    var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

    if (iOS) {
        $('body').addClass('iOS-device');
    }

    var scrollPosition;

    $('.modal').on('show.bs.modal', function() {
        scrollPosition = $(window).scrollTop();
        $('.iOS-device').css('top', -scrollPosition);
    });

    $('.modal').on('hide.bs.modal', function() {
        $('.iOS-device').removeClass('modal-open');
        $('.iOS-device').css('top', 0);
        $(document).scrollTop(scrollPosition);    
    });

})();

CSS

body.modal-open.iOS-device {
    position: fixed;
    width: 100%;
}

Ответ 12

добавить в #modal позицию: абсолютный он исправить будущие проблемы, связанные с позицией: fixed

Ответ 13

введите описание изображения здесь

Для такого рода проблем мы нашли следующие 3 решения

1) Измените контейнер с position: fixed; на position: absolute;. Недостатком этого является то, что пользователь может легко прокрутить прочь от модального, который мы хотели бы взять на себя в первую очередь в области недвижимости.

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

3) То, что мы нашли лучшим решением в нашем случае, - это сохранить модальный фиксированный, но растянуть его по краям окна, скрывая остальную часть содержимого в теле с помощью display: none;. Это позволит устранить проблему роста тела выше, чем область просмотра, и при фокусировке на входе не будет фоновой прокрутки.