2019-7-16 seo达人
如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里
先贴图,需要实现的效果是这样的。
实现思路有两个:
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界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 、平面设计服务。