【移動端debug-4】iOS下setTimeout沒法觸發focus事件的解決方案

開篇總結:其實目前沒法解決這個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去掉,從產品設計上避免。

若是你有什麼好的解決方案,歡迎留言哦!

相關文章
相關標籤/搜索