iOS 11 safari에서는 입력 텍스트 상자 커서가 입력 텍스트 상자 밖에 있습니다. 왜이 문제가 발생하는지 이해하지 못했습니다. 보시다시피 내 집중된 텍스트 상자는 이메일 텍스트 입력이지만 커서는 그 밖에 있습니다. 이것은 iOS 11 Safari에서만 발생합니다.
답변:
position:fixed
모달을 열 때 본체 에 추가하여 문제를 해결했습니다 . 이것이 당신을 도울 수 있기를 바랍니다.
width:100%
본체 너비를 장치 너비로 제한 하기 위해 추가해야 할 수도 있습니다 . 경우에 따라 기존 마크 업에 따라 문제가 될 수 있습니다. 나는 또한 @gentleboy (아래)의 솔루션을 좋아하여 문제없이 다른 브라우저에 불이익을주지 않기 위해 본문을 고정으로 설정하면 본문이 위쪽으로 스크롤되므로 다소 짜증이납니다.
position:fixed
신청서 본문에 신청했습니다. 대신 요소 position:absolute
에서 변경하고 html
내 문제를 해결했습니다. Jen 감사합니다!
개인적 position: fixed
으로 자동으로 맨 위로 스크롤합니다 . 꽤 짜증나!
다른 장치 및 버전에 대한 불이익을 피하기 위해이 수정 사항을 적절한 iOS 버전에만 적용합니다.
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%; }
클래스가있는 선택된 모달에 대해서만 실행되도록 함수를 수정했습니다. .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>
참고 사항 javascript 함수가 이제 자체 호출됩니다.
iOS 11.3부터 버그가 수정되었습니다. 테스트 할 필요가 없습니다 OS 11_
.iOS11 = /OS 11_0|OS 11_1|OS 11_2/.test(ua);
하지만 iOS 11.2가 여전히 널리 사용되고 있으므로주의하세요 (2018 년 4 월 현재). 보다
iOS11 = /OS 11_(\d{1,2})(_{0,1})(\d{1,2})/.test(us);
ios11 = /OS 11_(\d{1,2})/.test(ua);
이 문제는 부트 스트랩과 사파리를 넘어 섭니다. 모든 브라우저에서 발생하는 iOS 11의 전체 표시 버그입니다. 위의 수정으로 모든 경우에이 문제가 수정되는 것은 아닙니다.
버그는 여기에 자세히보고됩니다.
https://medium.com/@eirik.luka/how-to-fix-the-ios-11-input-element-in-fixed-modals-bug-aaf66c7ba3f8
아마도 그들은 이미 버그로 Apple 에보 고했습니다.
실망스러운 버그입니다. 확인해 주셔서 감사합니다. 그렇지 않으면 아이폰이나 머리를 벽에 부딪 히게됩니다.
가장 간단한 수정은 다음과 같습니다 (코드 한 줄 변경).
다음 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
of body
를 설정 fixed
하면iOS cursor misplacement
해결됩니다.
그러나 이러한 이득은 페이지 상단으로 강제 스크롤되는 비용으로 발생합니다.
다행히,이 새로운 UX
문제를 활용하여 많은 오버 헤드없이 부정 할 수 HTMLElement.style
및window.scrollTo()
.
기본 요점은 요소의 when scroll to top
을 조작하여 에 대응하는 것 입니다. 이 작업 은body
style.top
mounting
YOffset
ygap
변수가 .
거기에서 단순히 body's
style.top
to 를 재설정하고 when을 0
사용하여 사용자의 뷰를 재구성 하는 문제입니다.window.scrollTo(0, ygap)
dismounting
.
실제 예는 아래를 참조하십시오.
// 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
. 감사.
누구나 IOS> 11.2에서 작동하고 추가 CSS가 필요하지 않은 바닐라 js의 수정 사항을 찾고있는 경우 :
(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');
}
});