网站首页 > 技术文章 正文
演示结果
效果一:可依次输入验证码到输入框
效果二:可粘贴验证码到输入框
需求描述
实现修改手机号的功能,就包括了验证手机号,输入接受到的验证码。
拿到这个功能的时候,就在脑海里想着输入6位验证码,是应该放6个输入框吧,然后修改输入框的样式就可以了。说干就干呗。
画UI
UI图的效果大家看一下
聚焦和不聚焦的样式分别如上图,因为是在uniapp的框架下搭建的项目,使用的也是它们封装过的input组件框,所以在写样式的时候与原生input有点不一样。
上代码
<view class="input-code-view">
<input :class="['input-text', inputFocusObj['one']?'input-focus':'']"
type="number"
maxlength="1"
v-model="one"
label-position="left"
@focus="inputFocusObj['one']=true"
@blur="inputFocusObj['one']=false">
</view>
.input-code-view {
opacity: 1;
border-radius: 32rpx;
display: flex;
align-items: center;
justify-content: center;
.input-text {
width: 20rpx;
height: 96rpx;
padding: 0 38rpx;
border-radius: 32rpx;
background: #f6f6f6;
border: 2rpx solid #f6f6f6;
font-size: 32rpx;
font-family: Alibaba, Alibaba-PuHuiTi;
font-weight: PuHuiTi;
color: #333333;
line-height: 44rpx;
text-align: center;
}
.input-focus {
caret-color: #276ef1;
background: #eff3fe !important;
border: 2rpx solid #276ef1 !important;
}
}
看一下uniapp封装过的input,包裹了好几层
原生的input框
相对于修改原生的input框,修改已经封装好的要简单的多。把内层的样式改为失焦的样式,聚焦时修改外层的样式加上边框颜色和光标颜色。样式这块我们就完成了,看一下效果
可以看到我是把input输入框的宽度设为只有10px的大小,刚好只能容下一个数字的大小。为什么要设置这么小?主要是为了让我们在粘贴代码时感觉是自动复制上去,而不是人工控制。
自动跳转
这个谁不会呀?监听前一个输入框,当输入一个数以后聚焦到下一个输入框。我也是这么做的。
watch: {
one(val){
// 拿到input框 dom元素
let inputList = document.querySelectorAll('.uni-input-input');
if(Number(val) > -1) {
// 第二个dom 聚焦
inputList[1].focus();
}
},
}
问题接踵而至了。。。。
- 因为我们设置了最大长度为1,所以输入一次是ok的;但是第二次就输入不了。解决方案:因为最大输入长度为1,不能再输入,所以修改为每次聚焦都清空数据 @focus="inputFocusObj['one']=true;one=''"
<view class="input-code-view">
<input :class="['input-text', inputFocusObj['one']?'input-focus':'']"
type="number"
maxlength="1"
v-model="one"
label-position="left"
@focus="inputFocusObj['one']=true;one=''"
@blur="inputFocusObj['one']=false">
</view>
- 问题一导致了,如果输入框有数据存在的话,点击聚焦会触发if(Number(val) > -1)。解决办法:因为空字符串转为Number是0,所以首先判断是不是空字符串
watch: {
one(val){
let value = Number(val)
let inputList = document.querySelectorAll('.uni-input-input');
if((value || val === '0') && value>-1) {
inputList[1].focus();
}
},
}
自动跳转也Ok了。
自动带入粘贴数
这个???好好想想,我们只能把复制来的6位验证码放在第一个输入框,然后手动分配到后面的输入框去。
因为我们设置了最大长度为1,这个肯定是不能复制的。so把第一个输入框的最大长度改为6吧,这样就可以复制上去了。
<view class="input-code-view">
<input :class="['input-text', inputFocusObj['one']?'input-focus':'']"
type="number"
maxlength="6"
v-model="one"
label-position="left"
@focus="inputFocusObj['one']=true;one=''"
@blur="inputFocusObj['one']=false">
</view>
监听数据one,当数据长度大于1时,我们把多余的数都依次分配给后面的输入框。这里为什么要用到
watch: {
one(val){
let value = Number(val)
let inputList = document.querySelectorAll('.uni-input-input');
if ((value || val === '0') && value>-1 ){
if (val.length > 1) {
this.one = val.slice(0,1)
if (val.length > 1) {
this.two = val.slice(1,2)
}
if (val.length > 2) {
this.three = val.slice(2,3)
}
if (val.length > 3) {
this.four = val.slice(3,4)
}
if (val.length > 4) {
this.five = val.slice(4,5)
}
if (val.length > 5) {
this.six = val.slice(5,6)
}
} else {
inputList[1].focus();
}
}
},
}
问题又来了。。。
- 当我们粘贴123456的时候,发现第二、第四、第六输入框为空。仔细看我们的代码发现,当给第一个赋值时,触发了第二的聚焦事件,依次类推,所以导致了现在结果。解决方法:定义一个变量,标识我此时正在进行的是粘贴动作,要求代码不要执行聚焦事件。
watch: {
one(val){
let value = Number(val)
let inputList = document.querySelectorAll('.uni-input-input');
if ((value || val === '0') && value>-1 ){
if (val.length > 1) {
this.copyFlag = true
this.one = val.slice(0,1)
if (val.length > 1) {
this.two = val.slice(1,2)
}
if (val.length > 2) {
this.three = val.slice(2,3)
}
if (val.length > 3) {
this.four = val.slice(3,4)
}
if (val.length > 4) {
this.five = val.slice(4,5)
}
if (val.length > 5) {
this.six = val.slice(5,6)
}
setTimeout(() => {
this.copyFlag = false;
}, 0);
}
if(!this.copyFlag) {
inputList[1].focus();
}
}
},
two(val){
let value = Number(val)
let inputList = document.querySelectorAll('.uni-input-input');
if ((value || val === '0') && value>-1 && !this.copyFlag){
inputList[2].focus();
}
},
...
}
- 既然第一个输入框可以输入6个字符,当我们输入小数点时,光标竟然不自动跳转了,竟然可以一直输入,这肯定也是一个问题。解决方法:判断是否存在小数点,存在时,把数据置为0,然后把光标跳转。
watch: {
one(val){
let value = Number(val)
let inputList = document.querySelectorAll('.uni-input-input');
if ((value || val === '0') && value>-1 ){
if (val.length > 1) {
this.copyFlag = true
this.one = val.slice(0,1)
if (val.length > 1) {
this.two = val.slice(1,2)
}
if (val.length > 2) {
this.three = val.slice(2,3)
}
if (val.length > 3) {
this.four = val.slice(3,4)
}
if (val.length > 4) {
this.five = val.slice(4,5)
}
if (val.length > 5) {
this.six = val.slice(5,6)
}
setTimeout(() => {
this.copyFlag = false;
}, 0);
}
if(!this.copyFlag) {
inputList[1].focus();
}
}else {
if (val && String(val).indexOf('.') > -1) {
this.one = 0;
inputList[1].focus();
}
}
},
}
遗留问题
- 当粘贴超过6位数的时候,监听不到输入框的值
- uniapp未提供监听删除键盘事件,所以做不到依次删除数据
有什么问题可以留言讨论
猜你喜欢
- 2024-11-15 CSS3+JS实现静态圆形进度条(css 圆形进度条)
- 2024-11-15 前端必读榜——如何在React中用SpreadJS导入/导出Excel文件
- 2024-11-15 Svelte教程翻译(六、生命周期)(servelet生命周期阶段)
- 2024-11-15 国产开源,GoLang也可以高效处理Excel的利器了
- 2024-11-15 css精髓:这些布局你都学废了吗?(css布局技术)
- 2024-11-15 Java 中的 AI:使用 Spring Boot 和 LangChain 构建 ChatGPT 克隆
- 2024-11-15 仅用18行JavaScript实现一个倒数计时器
- 2024-11-15 Web上的图片技巧「前端篇」(web网页图片)
- 2024-11-15 55个JS代码让你轻松当大神(完整的js代码)
- 2024-11-15 导入vue的html、css、JavaScript的仿抖音的文字时钟代码解析
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-