業務場景:
小程序中有地方用到需要自定義輸入驗證碼或者密碼的地方,例如:
或者
這類場景。
需求:n個方框為輸入框,框中有光標,且光標隨着輸入字符移動,輸入完成后隱藏輸入框/自動校驗等
實現:方框用div模擬輸入框,然后一個輸入框覆蓋在方框div上,光標用動畫實現
偽代碼:
wxml文件:
<view class="input"> <view class="input-item" wx:for="{{4}}" wx:key="index" data-index="{{index}}"> <view class="input-value">{{password[index]}}</view> <view class="focus {{index === focusIndex ? 'show': 'hide'}}"></view> </view> <input class="input-password" maxlength="4" bindinput="setValue" bindblur="inputBlur" type="number" focus="{{focus}}"></input>
</view>
js文件:
Component({ /** * 組件的初始數據 */ data: { focusIndex: 0, // 光標所在位置 value: '', // 實際輸入的值 focus: true, // 是否獲得焦點 password: '', //替換顯示的值* }, /** * 組件的方法列表 */ methods: { setValue (e) { // 設置光標 var value = e.detail.value this.setData({ value: value, focusIndex: value.length, focus: value.length < 4, password: '*'.repeat(value.length) }) }, inputBlur (e) { if (e.detail.value.length === 4) { this.triggerEvent('complated', { value: e.detail.value }) } } } })
wxss文件:
.input { margin-top: 70rpx; padding: 0 60rpx; position: relative; } .input-item { position: relative; display: inline-block; width: 90rpx; height: 90rpx; border-bottom: 2rpx solid #333; } .input-item:not(:first-child) { margin-left: 26.67rpx; } .input-value { display: inline-block; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 28rpx; } .input-password { position: absolute; left: -360rpx; top: 0; height: 90rpx; width: 880rpx; opacity: 0; } .focus { width: 2rpx; height: 50rpx; background-color: #333; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } .show { display: block; animation: blink 1s linear infinite; } .hide { display: none; } @keyframes blink { 0%, 50% { opacity: 1; } 50.01%, to { opacity: 0; } }
大致這樣,password可以做明文替換為*
騷操作就是將input定位在自定義div上面,並且將input的寬度拉大,然后向左移動整個模擬div的寬度,隱藏掉它。