開篇總結:其實目前沒法解決這個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去掉,從產品設計上避免。
若是你有什麼好的解決方案,歡迎留言哦!