今天看到一个帖子,说到用input输入框模拟滴滴、摩拜等app验证码输入效果,提到了一个方案:
1、利用input来获得焦点,自动调用手机的数字键盘
2、实际将输入框用透明度隐藏
3、用label的for属性与input联动来显示输入的数字
于是照着这个思路实际操作了一番,还是发现了不少问题。
首先页面布局:
<div class="container"><h2>输入验证码:</h2><div class="vcode" id='vertifycode'><input type="tel" maxlength='6' ref='code' class='code' id='code'><div class="labels"><label class='label' for="code"></label><label class='label' for="code"></label><label class='label' for="code"></label><label class='label' for="code"></label><label class='label' for="code"></label><label class='label' for="code"></label></div></div></div>
样式:
@keyframes animate {100% {opacity: 0;}}.container{padding: 5%;}.vcode{position: relative;width: 100%;overflow: hidden;}.code{width: 100%;padding: 0;height: 40px;font-size: 35px;overflow: hidden;border: none;outline: none;opacity: 0;margin-left: -100%; // ios上透明度为0时依然有光标-webkit-tap-highlight-color: transparent;}.labels{display: flex;display: -webkit-flex;width: 100%;height: 40px;justify-content: space-between;-webkit-justify-content: space-between;margin-top: -40px;-webkit-tap-highlight-color: transparent;// 解决ios点击灰色阴影的问题}.label{height: 34px;width: 12%;border-bottom: solid 2px #313131;float: left;color: #313131;font-size: 35px;text-align: center;padding-bottom: 4px;}.active:after{ // 伪类实现光标效果content: ' ';display: inline-block;height: 100%;width: 2px;background: #313131;animation: .8s animate infinite;}
注意点:
1、ios手机上input和lable都会出现点击有灰色背景闪动的问题,所以一定要给样式加上
-webkit-tap-highlight-color: transparent;
2、输入框的默认光标隐藏了后,用伪类实现光标效果:
.active:after{ // 伪类实现光标效果content: ' ';display: inline-block;height: 100%;width: 2px;background: #313131;animation: .8s animate infinite;}
3、ios上虽然input透明度已经设置为0了,但是当其获得焦点时,默认的光标依然存在
可以利用margin将整个input输入框隐藏来解决:
margin-left: -100%;
样式写好了,就改进行逻辑处理了:
引入vue.js(vue确实好用)
<script src='./js/vue.min.js'></script>
更改页面布局:
<div class="container"><h2>输入验证码:</h2><div class="vcode" id='vertifycode'><input type="tel" maxlength='6' ref='code' class='code' id='code'@focus='focus=true'v-model='code'@blur='focus=false':disabled='disabled'><div class="labels"><label class='label' for="code":class='{active: focus===true && index===currentIndex}'v-for='item,index in length'v-text='arrCode[index]'></label></div></div></div>
逻辑代码:
new Vue({el: '#vertifycode',data: {length: 6,currentIndex: 0,code: '',focus: false,arrCode: [],disabled: false},computed: {arrCode: function () {return this.code.split('');},currentIndex: function () {return this.code.length;}},watch: {code: function (newV,oldV) {var self = this;this.code = newV.replace(/[^\d]/g,''); // 限制非数字console.log(newV);if(newV.length >= 6) {this.disabled = true;this.$refs.code.blur();setTimeout(function () {alert('submit:'+self.code+'');},500);}}}
数据说明:
length: 密码长度,根据实际需求设定;
currentIndex: 当前获得焦点的label的索引;
code: 输入的内容;
focus: 判断输入框的焦点状况;
arrCode:用于填充label标签内容;
disabled:控制输入框是否可用,输入6位验证码后禁用。
当输入长度等于6时,输入框失去焦点,自动提交数据,弹出提示框,实际效果: