在百度智能小程序的不少開發場景中,咱們都會使用到 Input 輸入框組件。而在操做輸入框的過程當中,正確處理鍵盤的彈出和收起行爲也是十分重要的一環。鍵盤行爲不只須要完美符合業務場景,同時也和用戶體驗息息相關。javascript
那麼,你真的徹底掌握了 Input 組件的鍵盤控制麼?html
更多招聘信息java
Input 組件的使用
在智能小程序的開發過程當中,開發者經過使用 Input 組件的 focus 和 blur 屬性來控制鍵盤,從而實現當用戶點擊 Input 框時,鍵盤彈起;當用戶點擊空白區時,鍵盤收起的效果。小程序
屬性名 | 類型 | 默認值 | 必填 | 說明 |
---|---|---|---|---|
focus | Boolean | false | 否 | 獲取焦點,調起鍵盤。開發者工具暫不支持自動獲取焦點 |
bindblur | EventHandle | 否 | 輸入框失去焦點時觸發,event.detail = {value: value} |
那麼智能小程序組件的開發同窗在開發 Input 組件的時候,又作了什麼呢?ide
讓咱們來深刻了解一下 Input 組件的實現原理。工具
Input 組件底層對 focus/bindblur 的處理
因爲百度智能小程序的 Input 組件是基於同層渲染來開發,咱們首先須要瞭解什麼是同層渲染技術。this
而在討論同層渲染前,咱們又須要先了解一下什麼是原生組件。code
原生組件
原生組件是小程序當中的一類特殊的內置組件,這類組件有別於 WebView 渲染的內置組件,他們是交由原生客戶端渲染的。component
原生組件有哪些優勢呢?
-
原生組件帶來了更加流暢的原生化體驗和更加豐富的控件功能。
-
提供 H5 組件沒法實現的一些功能,例如 H5 Video 不支持視頻格式優先、Canvas 不支持繪製本地圖片、Input 沒法調起客戶端定製的身份證鍵盤等。
-
使用原生控件減小了 H5 組件利用 JS 與 Objective-C(端)交互流程,下降了通訊開銷。
但原生組件也存在限制:
原生組件的層級是最高的。頁面中的其餘 H5 組件不管設置 z-index 爲多少,都沒法覆蓋原生組件,後插入的原生組件能夠覆蓋以前的原生組件。形成的影響有:
-
沒法支持在原生控件上覆蓋自定義 HTML 元素。
-
全部的 H5 彈出元素都會被原生控件遮擋,如 Alert 、Toast 等。
如何才能享用到原生組件的優勢,同時又能夠避開這些限制呢?同層渲染技術應運而生。
同層渲染與原生組件的關係
同層渲染是指經過必定的技術手段把原生組件直接渲染到 WebView 層級上,此時原生組件此時已被直接掛載到 WebView 節點上,能夠像使用非原生組件同樣去使用同層渲染的原生組件。
focus處理
咱們在上文已經理解了同層渲染的概念,Input 組件就是經過同層渲染技術實現的,可是在 IOS 和 Android 上的實現方式有一些差別。
-
Android 的 Input 組件是一個純 H5 組件,由前端和內核統一處理。NA 端的能力其實是經過API來與 NA端進行通訊,以後由客戶端去處理,例如:調起自定義鍵盤功能。
-
IOS 的 Input 組件全流程是一個 NA 組件,在未獲取焦點時,NA 組件是 DOM 樹中的一個節點,和其餘前端組件節點的區別是該節點是 NA 組件。在得到焦點的時候,該 NA 組件的視圖樹關係發生了變化,再也不繼承於 DOM 樹,而是客戶端 Webview 組件的一個子節點;再次失去焦點的時候,會再次將這個 NA 組件放回 DOM 樹當中。下圖以 IOS 的處理爲例:
- 首先 Input 組件會接收到開發者傳來的 focus 值並保存在 focus 變量中。
- 以後在用戶點擊時,將focus 變量置爲 true。
- 其次調 Input insert 端能力,與端通訊插入 input 標籤,組件底層觸發 bindFocus 方法,失去焦點後,觸發 bindBlur 方法。
- 最後底層會將 focus 的值設爲客戶端返回值。在觸發 blur 方法時,會銷燬 Input 原生組件。
須要注意的是,在觸發 bindConfirm 時,會觸發兩個事件:confirm 和 blur。IOS 端和 Android 端執行這兩個事件的順序有所差異,IOS 會先觸發 confirm 再觸發 blur; Android 端會先觸發 blur 再觸發 confirm。
Tips
這裏提供一些使用 Input 組件的 tips,幫助你避開一些體驗問題。
1. 避免快速切換 focus 的狀態。
以下圖的代碼段,會致使鍵盤雙次彈起,形成體驗問題。
// badcase data: { focus: true } searchFocus(e) { this.setData({ focus: false }, () => { this.setData({ focus: true }); }); } // goodcase data: { focus: true } searchFocus(e) { this.setData({ focus: true }); }
2. 不要濫用 blur 等變量。
客戶端會自動響應鍵盤的基本操做,因此開發者無需在 bindBlur 事件中去手動維護 blur 的值。
// badcase data: { blur: false } searchBlur(e) { // 沒有與blur有關邏輯下,更改blur狀態 this.setData({ blur: true }); }