最近做小程序,其中有一個短信驗證碼的填寫頁面,是那種輸入數字,就自動跳到下一格的,可以看下動圖
點擊橫線區域,彈出鍵盤,然後依次輸入數字,可自動跳到下一格,輸入完成後,下方確定按鈕自動變爲可點擊。
思路:
這個一開始我是以爲用 input 做好數字之間間隔,然後樣式再做好數字的對準即可,這樣子也可以隨意修改某個數字。後來做了之後,發現這樣子並不好操作,尤其是在樣式方面的控制,所以這種方法的做了一下就被我刪了重做了。
那麼另外的做法就剩下使用每個標籤來裝數字,每個標籤裝一個數字這種方法了,這種方法在樣式上控制起來就容易多了。我目前項目的驗證碼是6位數的,所以,需要有六個標籤來展示輸入,因爲要能夠輸入數字,所以需要有 input 標籤來存數字,然後每個標籤的數字就通過像取數組一樣,取到字符串內的每一個數字。有這種思路接下來就很容易把這個驗證碼輸入的給做出來了。
上代碼,直接複製到微信開發者工具上面可以直接預覽效果
wxml
<view class="modify_password">
<view class="tips">
<view>驗證當前手機號{{ currentMobile }}</view>
<view>爲了您的帳號安全,請輸入驗證碼</view>
</view>
<view class="code_area">
<view class="input_area">
<view bindtap="onFocus" id="0" class="{{ idx === 0 ? 'active' : '' }} {{code[0] ? 'hasValue' : ''}}">{{ code[0] }}</view>
<view bindtap="onFocus" id="1" class="{{ idx === 1 ? 'active' : '' }} {{code[1] ? 'hasValue' : ''}}">{{ code[1] }}</view>
<view bindtap="onFocus" id="2" class="{{ idx === 2 ? 'active' : '' }} {{code[2] ? 'hasValue' : ''}}">{{ code[2] }}</view>
<view bindtap="onFocus" id="3" class="{{ idx === 3 ? 'active' : '' }} {{code[3] ? 'hasValue' : ''}}">{{ code[3] }}</view>
<view bindtap="onFocus" id="4" class="{{ idx === 4 ? 'active' : '' }} {{code[4] ? 'hasValue' : ''}}">{{ code[4] }}</view>
<view bindtap="onFocus" id="5" class="{{ idx === 5 ? 'active' : '' }} {{code[5] ? 'hasValue' : ''}}">{{ code[5] }}</view>
<input class="hidden_input" type="number" bindinput="handleInput" maxlength="6" focus="{{ isFocus }}"></input>
</view>
<view class="countdown_tips" hidden="{{ !isSendCode }}">{{ times }}後重新發送</view>
<view class="resend" hidden="{{ isSendCode }}" bindtap="handleSendSms">重新發送</view>
</view>
<view class="btn_wrap">
<button class="{{ code.length === 6 ? 'ready' : 'wait' }}" bindtap="handleVerifyCode">確定</button>
</view>
</view>
JS
Page({
data: {
code: '',
isFocus: false,
idx: 0,
codeTimer: null,
times: '60s',
isSendCode: false,
currentMobile: '13800138000',
},
onLoad: function () {
this.setData({
})
this.handleSendSms()
},
onFocus (e) {
this.setData({
isFocus: true,
})
},
handleInput (e) {
this.setData({
code: e.detail.value,
idx: e.detail.value.length
})
},
// 發送短信驗證碼
handleSendSms () {
this.setData({
isSendCode: true,
endTime: new Date() - 0 + 60 * 1000
})
this.countdown()
},
// 倒計時
countdown () {
let currentTime = new Date() - 0
this.data.codeTimer = setTimeout(() => {
let remainTimes = parseInt((this.data.endTime - currentTime) / 1000)
this.setData({
times: remainTimes + 's'
})
if (remainTimes <= 0) {
clearTimeout(this.data.codeTimer)
this.setData({
isSendCode: false,
sendCodeText: '重新發送',
times: '60s'
})
} else {
this.countdown()
}
}, 1000)
},
handleVerifyCode () {
if (!this.data.code || this.data.code.length < 6) {
wx.showToast({
title: '請檢查驗證碼後重試',
icon: 'none'
})
}
}
})
wxss
.modify_password {height: 100%; overflow: hidden;}
.tips { text-align: center; margin-top: 45rpx;}
.tips > view {font-size: 28rpx; color: #999999; line-height: 40rpx;}
.tips > view:first-child {margin-bottom: 16rpx}
.code_area {margin-top: 29rpx;}
.input_area {height: 100rpx; display: flex; justify-content: center;}
.input_area > view { flex-shrink: 0; flex-grow: 0; line-height: 100rpx; font-size: 40rpx; width: 52rpx; height: 100rpx; margin-right: 48rpx; text-align: center; border-bottom: 4rpx solid #ccc; }
.input_area > view:nth-of-type(6) { margin-right: 0; }
.input_area > view.active {line-height: 92rpx;}
.hasValue {border-bottom: 4rpx solid #004BFF !important;}
.active:after {content: '|'; display: inline-block; animation: flash 1s 0s steps(1) both infinite;}
@keyframes flash {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
.countdown_tips {text-align: center; color: #999; margin-top: 48rpx;}
.resend {color: #004BFF; text-align: center; margin-top: 48rpx;}
.countdown_tips, .resend {font-size: 32rpx; line-height: 45rpx;}
.hidden_input {width: 0; height: 0; border: none;}
.btn_wrap {margin-top: 60rpx; }
.btn_wrap button {width: 670rpx; height: 94rpx; font-size: 34rpx; color: #fff;}
.wait {background-color: #6592FF; color: rgba(255, 255, 255, 0.6);}
.ready {background-color: #004BFF; color: rgba(255, 255, 255, 1);}
後面找時間我會把這個驗證碼輸入自動跳格的做成一個組件(vue),並且增加更多功能,方便使用。