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


開篇總結:其實目前無法解決這個bug。

這兩天做項目遇到了這個case,項目需求是打開頁面的時候,input元素自動彈起鍵盤。由於各種方面的考慮,我們希望通過setTimeout延時200毫秒讓input元素focus,demo代碼如下:

<!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沒有獲得焦點,問題出在哪了?

我通過debug發現,代碼能執行到setTimeout里面,並且input元素也沒有選擇失敗,那我們判斷是input.focus()這句失效了。

 

  • 前人指路

然后我們在stackoverflow上搜到了相關的case:Mobile Safari Autofocus text field

在最高票答案中,來自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()

里面也有人指出:

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去掉,從產品設計上避免。

如果你有什么好的解決方案,歡迎留言哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM