在百度智能小程序的不少开发场景中,咱们都会使用到 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 }); }