移动端 验证码/密码 输入框实现--安卓/ios适用 | |
【返回本版】 【发表帖子】 【回复帖子】 | 浏览量 984 回帖数 0 |
lanlan123 等级 ☆ 0 楼 发表于 2019/7/23 9:32:45 编 辑 |
||
实现思路有两个: 1、用6个input,输入一个数字后将focus给下一个输入框。 2、用一个input和6个span,input隐藏,用span显示。 现在大部分都是使用的第二种方法。(当然,如果你能说服产品也可以只用一个普通的input输入框,就什么都不用考虑了) 两种方案遇到的坑,以及优缺点,如下: 方案一:6个input。 主要就是用js切换focus,在安卓是相当流畅的,但是在ios会严重卡顿,简直逼死强迫症。 HTML: <div class="divYZM"> <!-- onpropertychange是为了避免在ios中oninput方法不被触发 --> <input id="check_1" class="numDiv" type="number" oninput="inputNext(check_1)" onpropertychange="inputNext(check_1)"/> <input id="check_2" class="numDiv" type="number" oninput="inputNext(check_2)" onpropertychange="inputNext(check_2)"/> <input id="check_3" class="numDiv" type="number" oninput="inputNext(check_3)" onpropertychange="inputNext(check_3)"/> <input id="check_4" class="numDiv" type="number" oninput="inputNext(check_4)" onpropertychange="inputNext(check_4)"/> <input id="check_5" class="numDiv" type="number" oninput="inputNext(check_5)" onpropertychange="inputNext(check_5)"/> <input id="check_6" class="numDiv" type="number" oninput="inputNext(check_6)" onpropertychange="inputNext(check_6)"/> </div> JS: function inputNext (id){ // 传过来的id是个对象 var index = Number(id.id.split("_")[1]) if (id.value.length < 1) { // 删除 id.value = '''' if (index > 1) { var preId = ''check_'' + Number(Number(index) - 1) document.getElementById(preId).focus() return false } } else { if(id.value.length>1) { var nextvalue = id.value.slice(1, 2) var nextId = ''check_'' + Number(Number(index) + 1) id.value = id.value.slice(0, 1) if ((index+1) <= 6) { document.getElementById(nextId).value = nextvalue document.getElementById(nextId).focus() } } } } PS:我这里写的删除方法是有问题的,这也是我果断放弃这种方案的原因之一。 如果正常输入,然后删除是可以的。 但是输入几个数后,先点击中间的框删除一个数字,再回到最后,便只能将中间到最后的这几个删掉,最前面的还需要手动点一下得到focus才能删除。 这对用户来说,简直太不友好了。。。 CSS: .divYZM{ width: 90%; margin: 0 auto; height: 100px; background-color: rgba(74, 35, 35, 0.42); } .numDiv{ display: block; width: 10%; float: left; border-radius: 5px; text-align: center; line-height: 60px; font-size: 20px; font-weight: 900; color: red; background-color: white; height: 60px; border: 0; padding: 0; margin: 0; margin-left: 5.7%; top: 20px; position: relative; caret-color: transparent; } 这里遇到的坑,举例一个。 input限制长度的属性maxlength a、与如下两种配合使用(tel也可以限制) <input type="text"> 或者 <input type="password"> b、当type为number时不起作用。这时需要用js控制。 <input type="number" oninput="if(value.length>5) value=value.slice(0,5)" /> 注意:此外,tel类型的input在ios上会调出全数字键盘,而number类型的input则会调出带有标点符号的键盘。 方案二:1个input和6个span。 隐藏input,用span显示内容。大坑就是,何种情况下能调起ios的软键盘呢? 先贴一下我刚开始的input样式。 width: 0; height :0; border: 0; padding: 0; margin: 0; 第二种 display:none; 简单粗暴,结果就是,ios木得反应。为啥呢,我想不通。 后来在晚上睡觉的时候我在想,我这两种方式input都么有占位啊,那是不是占位了就可以了呢? 经测果然是可以的(默默谴责自己懒了一下,没有将不隐藏input的情况,在手机上进行测试)。 接下来贴正确代码。 CSS: #yzm{ width: 0; border: 0; padding: 0; margin: 0; height: .44rem; position: absolute; outline: none; color: transparent; text-shadow: 0 0 0 transparent; width: 300%; margin-left: -100%; } #yzmTable { width: 90%; margin: 0 auto; height: 100px; /* border: 1px solid red; */ background-color: rgba(74, 35, 35, 0.42); /* opacity: 0.1; */ } #yzmTable span { display: block; width: 10%; float: left; border-radius: 5px; text-align: center; line-height: 60px; font-size: 20px; font-weight: 900; color: red; background-color: white; height: 60px; margin-left: 5.7%; top: 20px; position: relative; } 这里对input的样式也包括对光标的隐藏,我在第一种方案中对光标未进行处理,因为在看到ios的卡卡卡之后果断放弃了第一种方案。 HTML: <input id="yzm" type="tel" maxlength="6" value="" oninput="yzmInsert()"> <div id="yzmTable"> <span id="s_1" onclick="intoYzm(1)"> </span> <span id="s_2" onclick="intoYzm(2)"> </span> <span id="s_3" onclick="intoYzm(3)"> </span> <span id="s_4" onclick="intoYzm(4)"> </span> <span id="s_5" onclick="intoYzm(5)"> </span> <span id="s_6" onclick="intoYzm(6)"> </span> </div> js: function intoYzm(index) { var ele = document.getElementById("yzm") ele.focus() } function yzmInsert() { // input内容改变时触发 for (var i = 1; i <= 6; i++) { var nextId = ''s_'' + i document.getElementById(nextId).innerHTML = '' '' } var yzm = document.getElementById("yzm").value var yzmArr = yzm.split(''''); for (var i = 0; i < yzmArr.length; i++) { const num = yzmArr[i]; var id = ''s_'' + Number(i + 1) document.getElementById(id).innerHTML = '' '' + num + '' '' } } // 收起软键盘的方法,点击除了输入框之外的其他区域就收起软键盘 $(''body'').on(''touchend'', function(el) { if(el.target.tagName != ''SPAN'') { $(''yzm'').blur() } }) 在第二种方案中有两个地方注意下: a、在js方法中加了对全局中6个span标签(即六个输入框)之外区域点击事件的监听,用以收起软键盘,方法如下。 $(''body'').on(''touchend'', function(el) { if(el.target.tagName != ''SPAN'') { $(''yzm'').blur() } }) (比较粗糙,如果页面中还有别的部分就比较受影响了,可以自行改进) b、在隐藏的input中添加了onclick方法,如下并且在其中用了blur方法使得此输入框失去焦点。为什么这么做呢? <input id="yzm" type="tel" maxlength="6" value="" oninput="yzmInsert()" onclick="this.blur();"> 因为此处的隐藏并非真正的隐藏,而是透明化处理,边框包括光标全部透明化,但实际上它还是占位的,所以当你点击输入框上方空白处时,仍会唤起软键盘,就和我们之前所想的点击输入框之外区域就收起软键盘冲突了。 因此将input自身的点击获取focus禁止掉,就OK了。 之前都是自己乱七八槽的瞎记,第一次写给别人看,经验不足,时间仓促。不足之处,还望指正。 蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 、平面设计服务。 |
1 |