请选择 进入手机版 | 继续访问电脑版
MSIPO技术圈 首页 IT技术 查看内容

记录一次解决uniapp自定义验证框的bug过程

2023-07-13

问题起源:
本来是使用自定义软盘,但是因为无法实现粘贴验证码的问题,最终打算采用原生自带的软盘来处理

问题路程:
1、点击验证码框时候可以实现隐藏和切换是否聚焦状态,但是没有考虑到点击验证码以外位置时候,也会触发取消聚焦,而且刚好没有输入框绑定了取消聚焦的事件,所以软盘隐藏了,而且isFocus还是true,再次点击验证码输入框时候,需要点击两次才能再次唤起软盘
2、在1的基础上改进了:在输入框上添加了@blur 事件,当取消聚焦时候设置isFocus为false,但是又出现这样一个问题,在点击验证码输入框时候,首次可以进行弹起,但是如果二次点击验证码输入框会出现弹起后无法进行关闭,这是因为input的@blur刚好设置为false,然后立马又被绑定在验证码输入框上的事件修改为true了,所以再次弹起
3、在2的基础上做修改:将input上的@blur移除,实现,点击验证码输入框时候能正常显示隐藏,但是点击除了验证码输入框以外的事件时候将isFocus设置为false,表示已经取消聚焦。但是这里要注意验证码输入框上事件可能会传播到最外层的事件也就是会触发到验证码输入框以外的事件
4、虽然3看似已经没有问题了,但是发现又存在一个问题:点击键盘的完成事件时候,触发输入框的取消聚焦事件 软盘被收回了,但是isFocus还是true,这个时候再次点击验证码输入框时候,需要点击两次
5、针对4的问题,打算通过监听软盘的显示与隐藏来设置isFocus ,如果高度变为0表示取消聚焦了,则将isFocus设置为false,,同时移除在3当中验证码输入框以外的监听事件,而且将@blur移除,这个时候就是只剩下验证码输入框点击修改isFocus 以及 监听键盘事件了。
6、这个时候,正常来说,应该不会有啥问题了,不过当我快速点击验证码输入框位置进行显示与隐藏时候,发现有时候,点击两次软盘都是隐藏又立马弹起,无法进行隐藏,这个问题不知道问题所在,所以我打算,在点击验证码输入框时候,保持软盘处于弹起状态,点击其他位置时候才进行隐藏。本来以为点击验证码输入框时候,保持isFocus为true就不会导致软盘隐藏的,但是实际上问题并没有这么好解决,最终找来代码,是直接阻止触摸屏幕的事件,也就是点击验证码输入框时候,阻止屏幕事件的默认行为,保持isFocus为true,这样子也不会导致input取消聚焦,点击前天位置时候,还是正常触发触摸事件默认行为,取消聚焦设置isFocus为false。

另外还有一个问题就是,input在ios上面,如果填充了内容,再次聚焦输入框时候,无法让光标展示在最后面,查看了相关文档看到了这么一个属性

:selection-start="datas.validateCode.length+1" 
:selection-end="datas.validateCode.length+1"

只需要加上这个代码就可以了,但是这个东西有局限性,就是只有首次聚焦时候才会生效
为了解决这个问题,实现每次isFocus为true聚焦时候都能实现光标在结尾处,所以我也设置input根据isFocus来决定显示与隐藏,相当于重新创建又生成input,这样子感觉每次都是首次聚焦了。

最终关键代码如下:
验证码输入框

<view class="d-flex  a-center j-sb " @touchend.prevent="focus" style="padding: 0 90rpx;">
					<view :class="[!code[0] && !code[1] && !code[2] && !code[3] ? 'border-active' : 'border-muted']"
						class="smsInput mborder  rounded d-flex j-center a-center" style="font-size: 74rpx;">
						{{ code[0] }}
					</view>
					<view :class="[!code[1] && code[0] && !code[2] && !code[3] ? 'border-active' : 'border-muted']"
						class="smsInput mborder  rounded d-flex j-center a-center" style="font-size: 74rpx;">
						{{ code[1] }}
					</view>
					<view :class="[!code[2] && code[0] && code[1] && !code[3] ? 'border-active' : 'border-muted']"
						class="smsInput mborder  rounded d-flex j-center a-center" style="font-size: 74rpx;">
						{{ code[2] }}
					</view>
					<view :class="[!code[3] && code[0] && code[1] && code[2] ? 'border-active' : 'border-muted']"
						class="smsInput mborder  rounded d-flex j-center a-center" style="font-size: 74rpx;">
						{{ code[3] }}
					</view>
				</view>

真实的input输入框

<input :selection-start="datas.validateCode.length+1" :selection-end="datas.validateCode.length+1"
					v-if="isFocus" style="position: fixed;left: -100px;" type="text" ref="inputRef" maxlength="4"
					@input="inputFilter" :focus="isFocus" :type="$isIos?'number':'tel'" v-model="datas.validateCode">

绑定键盘高度监听

uni.onKeyboardHeightChange(res => {

				if (res.height == 0) {
					this.isFocus = false;
				}
			})

聚焦事件

/**
			 * 输入框聚焦
			 */
			focus(type) {
				if (!this.isFocus) {
					this.isFocus = true;
				}
			},

相关阅读

手机版|MSIPO技术圈 皖ICP备19022944号-2

Copyright © 2023, msipo.com

返回顶部