首先看看我们要实现的效果

一、
效果和很多密码框一样,一个个输入。初看到这个效果感觉很简单,外层一个view,里面来8给text设置右边框为虚线,页面上就实现了效果。然后用一个input标签,定位在这个view上面。只要设置下input里面的字符间距。这里面有一个移动端也会遇到的设置字符间距问题,即是如果设置字符间距以后,input标签在输入前七个是没有问题的,当输入第八个数字的时候,因为要给光标留位置,所以整体会往前缩进,导致布局乱掉。
在小程序中抛开这个问题,小程序的input居然设置不了字符间距
二、
第一种方法pass掉,我们想想第二种方法,对,就用8个input标签,为了吸取上面的教训,先来看看小程序的input组件能不能手动设置聚焦,主要思路就是一个input标签输入完成以后马上失去焦点,让下一个input获取焦点。等等,这样切换小程序键盘会不会跟着切换?算了,试一下看看。于是又动手做了一波。
神奇的预言,效果可以实现输入和删除,可是键盘总是一闪一闪的,这用户体验会摔手机的好吧
三、
好汉不吃眼前亏,重新写过,综合两次经验,那就这样写吧,一个view把8个text包裹,先形成八个空格,然后用一个input标签定位在view,宽高都设为100%,z-index= -1,让其在view标签下面,不要被我们看到,然后输入的数字这一一映射到八个空格子里面,光标就用一个setTimeout循环显示隐藏。这样目测没什么问题了。开始动手一顿。
哈哈哈,开发这工具里面没什么问题了,效果可以实现了,用手机测试下,我去,隐藏不了,z-index没用;好我改,font-size我设置为0,还是隐藏不了;ok,那我再改,opacity我设置为:0,现在有用了吧,去,还没用。这个时候一脸懵逼
那就只能使用终极奥义,input的宽高设置为:0;现在出不来了吧,然后给外层view一个点击事件,动态的给那个不知道哪里去了的input获取焦点,然后输入数据,完成!!
最后看看源码吧,样式就不给出来了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <view > <image></image> <text>请输入8位电桩编号</text> <text bindtap='scanCode'>点击扫码</text> </view> <view class="code_box"> <input bindinput='numberChange' type='number' maxlength='8' focus='{{focusShow}}' bindblur='{{loseBlur}}' value='{{boxCode}}'></input> <view catchtap='showKeyboard'> <view data-id='0'><text>{{boxcodearr[0] == "undefind" ? "" : boxcodearr[0]}}</text><text class='cursor {{focusnum == 1 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='1'><text>{{boxcodearr[1] == "undefind" ? "" : boxcodearr[1]}}</text><text class='cursor {{focusnum == 2 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='2'><text>{{boxcodearr[2] == "undefind" ? "" : boxcodearr[2]}}</text><text class='cursor {{focusnum == 3 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='3'><text>{{boxcodearr[3] == "undefind" ? "" : boxcodearr[3]}}</text><text class='cursor {{focusnum == 4 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='4'><text>{{boxcodearr[4] == "undefind" ? "" : boxcodearr[4]}}</text><text class='cursor {{focusnum == 5 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='5'><text>{{boxcodearr[5] == "undefind" ? "" : boxcodearr[5]}}</text><text class='cursor {{focusnum == 6 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='6'><text>{{boxcodearr[6] == "undefind" ? "" : boxcodearr[6]}}</text><text class='cursor {{focusnum == 7 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> <view data-id='7'><text>{{boxcodearr[7] == "undefind" ? "" : boxcodearr[7]}}</text><text class='cursor {{focusnum == 8 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view> </view> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| data: { boxcodearr: [], focusnum: 0, focusShow: false, cousor : true, cursorMove: "" },
numberChange: function (e) { console.log(e) var value = e.detail.value.replace(/[\D]/g, ''); var arr = value.split(''); this.setData({ boxcodearr: arr, boxCode : value }) this.judgeFocus(); if (this.data.boxCode.length == 8) { this.getBoxDetail(); } else { this.boxCodeVerify(); } }, showKeyboard : function (e) { this.setData({ focusShow: true }) console.log(e.target.dataset.id); this.judgeFocus(); }, loseBlur : function (e) { console.log(e) this.setData({ focusnum: 0 }) }, judgeFocus: function () { var arr = this.data.boxcodearr; var num = arr.length; if(num == 0) num = 1; this.setData({ focusnum : num }) }, flashd : function () { var that = this; move(); function move() { that.setData({ cousor : !that.data.cousor }) that.cursorMove = setTimeout(move,500); } }
|
上面写的输入框可以实现基本功能,但是,只能够从最后一个位置开始删除,每次光标都出现的第一个没有数字的框
顾客是上帝,客户说要实现点击了哪个框删,就可以单独更改那个框,好吧,那就改呗
最终方案的逻辑不变,只需要做一些简单的改动。
上面方案三的显示的数字和input的值是挂钩的,那么我们把它们分成两个不同的,互相不影响。用光标的位置来对应每个框相应的值改变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| numberChange: function (e) { console.log(e); var value = e.detail.value.replace(/[\D]/g, ''); var arr = this.data.boxcodearr; var focusnum = this.data.focusnum; var boxCode = this.data.boxCode; if (value.length > boxCode.length) { var num = value[value.length - 1]; console.log(num); if (arr[focusnum - 1] == "") { arr[focusnum - 1] = num; this.judgeFocus(true); } else { this.judgeFocus(true,true); } } else { if (arr[focusnum - 1] == "") { this.judgeFocus(false); } else { arr[focusnum - 1] = ""; this.judgeFocus(false, true); } value == "" ? value = "520" : value; } console.log(value) this.setData({ boxCode: value, boxcodearr: arr }) this.judgeGet(arr); }, judgeFocus: function (add, noChange) { var focusnum = this.data.focusnum; if (add) { focusnum++; focusnum >= 8 ? focusnum = 8 : focusnum; } else { if (!noChange) { focusnum--; focusnum <= 1 ? focusnum = 1 : focusnum; } } console.log(focusnum); this.setData({ focusnum: focusnum }) }, judgeGet(arr) { var use = true; for (var i = 0; i < arr.length; i++) { if (arr[i] == "") { use = false } } if (use) { this.getBoxDetail(); } else { this.boxCodeVerify(); } }
|