开篇总结:其实目前没法解决这个bug。html
这两天作项目遇到了这个case,项目需求是打开页面的时候,input元素自动弹起键盘。因为各类方面的考虑,咱们但愿经过setTimeout延时200毫秒让input元素focus,demo代码以下:jquery
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>IOS下setTimeout没法触发focus事件的解决方案</title> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"> </head> <body> <div id="container"> <input id="input-box" type="text" placeholder="click here to focus."> </div> <script> var container = document.getElementById("container"); var input = document.getElementById("input-box"); setTimeout(function () { input.focus(); },200); </script> </body> </html>
上面的代码在pc上显示没有问题,可是在安卓上也ok,可是在ios上出了问题,input没有得到焦点,问题出在哪了?ios
我经过debug发现,代码能执行到setTimeout里面,而且input元素也没有选择失败,那咱们判断是input.focus()这句失效了。git
而后咱们在stackoverflow上搜到了相关的case:Mobile Safari Autofocus text fieldgithub
在最高票答案中,来自FastClick团队的大牛指出了IOS下input的获取焦点存在这样的问题:编程
my colleagues and I found that iOS will only allow focus to be triggered on other elements, from within a function, if the first function in the call stack was triggered by a non-programmatic event. In your case, the call to setTimeout
starts a new call stack, and the security mechanism kicks in to prevent you from setting focus on the input.安全
翻译:我和个人同事发现,iOS将只容许在其余元素上绑定函数来触发focus事件,若是第一个函数调用栈是由非编程触发的事件(这句不知道怎么翻译)。在你的案例中,调用setTimeout开始一个新的调用堆栈,IOS的安全机制开始阻止你触发input元素的focus事件。函数
github上也有相关的issue:iOS does not show keyboard on .focus()测试
里面也有人指出:spa
iOS won't, as far as I can tell from testing, show the keyboard without some kind of user interaction.Trying a setTimeout to load it doesnt work. But setting the focus on another element's onClick event brings it up.
翻译:据我目前测试所知,若是没有经过某种用户交互,iOS不会(触发focus事件)。用setTimeout试图触发focus不工做(setTimeout是延时触发,非用户交互的当下触发focus),但设置另外一个元素的onClick事件,就能把focus事件带起来。
//经过在input之外的其余元素绑定事件能够触发input元素的focus事件 container.addEventListener("click",function(e){ input.focus(); });
目前看来没有更好的办法能在iOS下,经过setTimeout调起focus事件,因此只能把setTimeout去掉,从产品设计上避免。
若是你有什么好的解决方案,欢迎留言哦!