iOS 11 Safari在光标外引导模态文本区域
使用iOS 11 safari,input文本框光标在input文本框之外。 我们没有得到为什么它有这个问题。 正如你所看到的我的焦点文本框是电子邮件文本input,但我的光标是在它之外。 这只发生在iOS 11 Safari上
我通过添加position:fixed
来解决问题position:fixed
打开模式时position:fixed
在身体上。 希望这会帮助你。
个人而言, 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%; }
更新1添加版本操作系统11.1作为错误仍然在这个版本
这个问题超越了Bootstrap,超越了Safari。 这是在所有浏览器中发生的iOS 11中的完整显示错误。 上面的修复程序在所有情况下都不能解决这个问题。
这个bug在这里有详细的报告:
https://medium.com/@eirik.luka/how-to-fix-the-ios-11-input-element-in-fixed-modals-bug-aaf66c7ba3f8
据说他们已经把它报告给苹果了。
令人沮丧的错误,感谢识别它。 否则,我会把我的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">×</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>
最简单/最干净的解决scheme:
body.modal-open { position: fixed; width: 100%; }
添加position: fixed;
当模态打开时,
$(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>
Incase任何人正在寻找修复在香草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 } })()
这是做什么的:
- 检查浏览器是否是iOS 11.0.0 – 11.2.5上的Safari
- 聆听页面上的任何
focusin
事件 - 如果焦点元素是
input
或textarea
,并且包含在具有fixed
位置的元素中,则将关于scrollTop
和容器原始尺寸的容器位置更改为absolute
。 - 模糊时,将容器的位置恢复到
fixed
。
你有没有为元视口尝试viewport-fit = cover 。
看看这个: https : //ayogo.com/blog/ios11-viewport/
覆盖模态CSS并将其position
从fixed
改为absolute
.modal { position: absolute !important; }
正如gentleboy提到的那样,将body设置为position:fixed会自动使页面滚动到顶部。 将容器的位置设置为绝对位置会使后者出现在其最近定位的祖先或身体的顶部,因此如果用户向下滚动,他甚至可能看不到该模式。
解决方法是将主体的位置设置为固定,然后将scrollTop传递给一旦修复的主体的顶部或顶部CSS属性。 当closures模态时,执行相反的操作来检索用户在打开模态之前所在的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错误,并在所有设备上工作。
正如许多人所描述的那样,问题是:
position:fixed
现在,如果你打开模式,你会被扔到页面的头部 …为了避免我使用这个解决scheme(接近@威尔的)。
首先我确定设备是iOS:
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
如果设备是iOS,则将iOS设备类添加到主体中:
if (iOS) { $('body').addClass('iOS-device'); }
使variables保持滚动位置:
var scrollPosition;
现在检测show.bs.modal事件并将iOS设备的顶级属性设置为负的scrollPosition:
$('.modal').on('show.bs.modal', function() { scrollPosition = $(window).scrollTop(); $('.iOS-device').css('top', -scrollPosition); });
接下来,检测hide.bs.modal事件,删除模式公开类,重置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%; }
添加到#modal的位置:绝对它修复有关位置的未来问题:固定
对于这类问题,我们发现了以下三种解决scheme
1)将容器从position: fixed;
改变position: fixed;
position: absolute;
。 不利之处在于,用户可以轻松地从我们想要占据窗户房地产的模式中滚动出来。
2)你可能会认为模态在小屏幕上运行的不好,最好的解决办法是根本不使用模态,但在我们的例子中,这将是一个很大的重写,我们需要尽快修复尽可能。
3)在我们的例子中,我们发现最好的解决scheme是保持模式固定,但是将其拉伸到窗口的边缘,用display: none;
隐藏其余的内容display: none;
。 这将消除身高高于视口的问题,并且在关注input时不会出现背景滚动。