當前位置:
首頁 > 知識 > 移動端 Web頁input 控制軟鍵盤

移動端 Web頁input 控制軟鍵盤

從交互層面上來講,完成一個功能(獲得想要的信息)的過程稱之為用戶路徑。用戶路徑越長,完成功能的複雜度就越高,用戶體驗也就越差。因此當打開一個需要用戶填寫信息的表單界面時,為了提高可用性,PC 端一般會將游標聚焦到對應輸入框(input),移動端也是同理,讓對應的 input 獲得 focus 狀態,喚起軟鍵盤,方便用戶直接輸入。

本文暫且不論 PC 端的場景,在移動端(iOS、Android)實現這個看似不起眼的效果其實是需要經過一番折騰,我們慢慢往下看以下三種常用場景。

一、當進入表單頁時,讓軟鍵盤自動打開

這個需求比較常見,但是也是最棘手的。講科學的話,我們可以直接在 JS 里獲取 input ,給它 focus 下就搞定了。但是這在移動端瀏覽器里是行不通的。。

另外,H5 提供了 autofocus 屬性,這個屬性的兼容性在 caniuse 上顯示並不支持 iOS Safari,Android 也是要到 4.4 才開始支持,因此我們可以忽略這個屬性,不過下文會再次提到這個屬性。

因此在 iOS 里想要在頁面 load 完成後自動聚焦 input,打開鍵盤目前來講不是很現實。

最難過的是 Android 也不行,目前進行了簡單的測試系統瀏覽器和 App 內嵌 WebView,H5 中的 input 是聚焦狀態,但是無法喚起鍵盤,鍵盤,鍵盤。。。

場景一,暫時無解……(下文提到在 Hybrid App 中可以實現)

二、當點擊頁面中某個元素喚起軟鍵盤

這個相對於場景一,多了用戶交互這一步。那麼這樣是不是就可以使用 JS 在 iOS 上成功的喚起鍵盤了呢?答案是肯定的。

如果有使用 zepto 的童鞋,這邊需要注意下為了 iOS,你不能使用 tap 事件。

如上使用了 zepto tap 事件,它在 iOS 上並不能達到預期效果,這裡面就涉及到了 iOS WebView 的一種默認安全機制。在 UIWebView 中有一個屬性:

這個屬性默認是 YES,也就是說鍵盤的出現必須要用戶交互。那我們就知道原因了,zepto 內部觸發 tap 事件是在 setTimeout 內,也就是說執行 focus 時,執行環境並不是用戶觸發的,因此 focus 被攔截掉了。

如果我們是寫 Hybird App 的頁面,則可以讓 Native Coder 將 UIWebView 的 keyboardDisplayRequiresUserAction 屬性設置為 NO,則不必操心這個問題了。

不過 iOS 的 WKWebView 不支持這個屬性了,但是在 StackOverflow 上有方案,可以使用 runtime 的 method swizzling hack 掉,詳見此鏈接stackoverflow.com/questions/3…

那麼場景一在自己的 Hybrid App 里還是可以實現的,當然系統原生的 Safari 瀏覽器我們無能為力,能優化一點是一點吧。

同時測試了下 autofocus 屬性,在 keyboardDisplayRequiresUserAction 設置為 NO 的情況下,它也是能正常工作的。

在 Android 底下,也是可以實現用戶點擊之後 focus 指定 input 的效果,而且沒有 iOS 的那個機制。

三、表單頁多個 input 依次自動聚焦

這個場景其實是場景一、二的結合,綜合上面兩個場景的測試分析,在自己的 * iOS Hybrid App * 里依賴 Native 的 WebView 是可以實現的,在 Android 和外部瀏覽器中可以實現除第一次聚焦外的自動聚焦。。

目前 iOS UIWebView 設置 keyboardDisplayRequiresUserAction = NO 的狀態下,需要在 blur 事件內延遲 focus 才能生效(具體原因暫時不明):

在系統 Safari 內,則因為 keyboardDisplayRequiresUserAction 默認為 YES,因此不允許在用戶交互產生的執行環境之外調用 focus,因此不能延遲執行。

而在安卓中,頁面載入完後自動聚焦仍舊只是出現游標,不彈出鍵盤。。。後續自動聚焦則沒問題,如下圖所示狀態。。。

為了解決這個問題,在 Hybrid App 中可以通過 JSBridge 讓 Android 原生進行喚起,後續 blur 事件中再 focus 則不需要原生再進行處理。

小結

總結下:

要實現頁面載入完成後自動聚焦到 input 並彈出鍵盤,依賴 iOS App 的 WebView 將 keyboardDisplayRequiresUserAction 設置為 NO,就可以支持。Android 底下只能依賴 JSBridge 調用 Android 原生方法喚起鍵盤 。

點擊元素聚焦指定 input,iOS / Android 都支持,但是 iOS 中必須保證 focus 是在用戶操作事件的函數執行環境中直接調用(Zepto tap 的坑)。

依次聚焦 input,iOS 中有點特殊,具體還是看上文場景三。。。

LINKS

作者:boban

原文:https://webfe.kujiale.com/mobile-input-auto-focus/


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 JavaScript 的精彩文章:

2018秋招前端面經總結
前端代碼合集
前端進階之路:如何高質量完成產品需求開發
你們覺得 vscode 的新 logo 怎麼樣?
Chrome 調試工具的一些高階功能

TAG:JavaScript |