iOS下Html页面中input获取焦点弹出键盘时挡住input解决方案—scrollIntoView()
问题描述
iOS系统下,移动web页面,inpu获取焦点弹出系统虚拟键盘时,偶尔会出现挡住input的情况,尽管概率不大,但是十分影响用户体验。
问题重现
原始页面:页面中有header、main、footer三部分,其中 header 和 footer 通过 position: fixed; 定位在浏览器顶部和底部。
其中,footer 中有一个input 输入框。
点击 input 框使之获取焦点,唤起虚拟键盘,正常页面效果如下:
注:在ios系统唤起软键盘,键盘和底部输入框之间有一块空白间距。
但是偶尔会出现软键盘挡住input框的情况,如下:
针对此问题,目前没有十分有效的方法,只能通过js调整input输入框的位置,使之出现在正常的位置。
解决方法
scrollIntoView(alignWithTop): 滚动浏览器窗口或容器元素,以便在当前视窗的可见范围看见当前元素。
alignWithTop 若为 true,或者什么都不传,那么窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐;
alignWithTop 若为 false,调用元素会尽可能全部出现在视口中,可能的话,调用元素的底部会与视口顶部平齐,不过顶部不一定平齐。
支持的浏览器:IE、Chrome、Firefox、Safari和Opera。
该方法是唯一一个所有浏览器都支持的方法,类似还有如下方法,但是只有在Chrome和Safari有效:
scrollIntoViewIfNeeded(alignCenter)
scrollByLines(LineCount)
代码如下:
再次测试,效果如下:
相比于input被挡住,突兀地出现在页面中间更加可以令人接受,但是多次测试,仍然存在问题:当切换输入法的时候,input框的位置会往下移动,被键盘挡住一部分,而且出现的概率比较高(中英文切换),效果如下:
针对这个问题,后期仍需要继续调试和优化。
针对input输入框被虚拟键盘挡住的问题,还有一个类似的解决方案:
当软键盘被唤起是,使用 scrollTop() 方法使input元素滚动到指定的位置,但是滚动的具体数值需要调试才能给出,所以这里就不再演示了。
虚拟键盘挡住输入框一直是web开发中的一个无法避免且令人头疼的问题,希望有人能够想出的更好的办法,如果是浏览器或者系统的问题,希望官方可以尽快解决。
参考资料:《JavaScript高级程序设计》P298
Demo 完整代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"> 5 <title><%= title %></title> 6 <link rel='stylesheet' href='/css/style.css' /> 7 <script src="/js/jquery-3.1.1.min.js" charset="utf-8"></script> 8 <style> 9 html, body { 10 height: 100%; 11 padding: 0; 12 margin: 0; 13 } 14 header { 15 position: fixed; 16 top: 0; 17 left: 0; 18 z-index: 9999; 19 width: 100%; 20 height: 50px; 21 line-height: 50px; 22 font-size: 18px; 23 text-align: center; 24 background: #ccc; 25 } 26 main { 27 position: absolute; 28 top: 50px; 29 bottom: 10px; 30 left: 20px; 31 width: 100%; 32 margin-bottom: 50px; 33 /* 使之可以滚动 */ 34 overflow-y: scroll; 35 /* 增加该属性,可以增加弹性,是滑动更加顺畅 */ 36 -webkit-overflow-scrolling: touch; 37 } 38 footer { 39 position: absolute; 40 bottom: 0; 41 left: 0; 42 width: 100%; 43 height: 50px; 44 line-height: 50px; 45 text-align: center; 46 background: #666; 47 border-top: 1px solid #e6e6e6; 48 } 49 footer input { 50 display: inline-block; 51 width: 90%; 52 height: 20px; 53 font-size: 14px; 54 outline: none; 55 border: 1px solid #e6e6e6; 56 border-radius: 5px; 57 } 58 </style> 59 </head> 60 <body> 61 <header> 62 This is the header 63 </header> 64 <main> 65 <h1><%= title %></h1> 66 <p>Welcome to <%= title %></p> 67 <ul> 68 <li>Today</li> 69 <li>is</li> 70 <li>Sunday</li> 71 <li>And</li> 72 <li>I</li> 73 <li>have</li> 74 <li>to</li> 75 <li>go</li> 76 <li>to</li> 77 <li>work</li> 78 <li>tomorrow</li> 79 </ul> 80 </main> 81 <footer> 82 <input type="text" placeholder="Type here..."> 83 </footer> 84 </body> 85 <script type="text/javascript"> 86 $(function() { 87 $('input').on('click', function () { 88 var target = this; 89 // 使用定时器是为了让输入框上滑时更加自然 90 setTimeout(function(){ 91 target.scrollIntoView(true); 92 },100); 93 }); 94 }) 95 </script> 96 </html>