业务场景:
小程序中有地方用到需要自定义输入验证码或者密码的地方,例如:
或者
这类场景。
需求: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; 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; 880rpx; opacity: 0; } .focus { 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的宽度,隐藏掉它。