emmmm...这个功能不知道怎么概括好,看图说话吧
实现该功能的大体思路:
1、画一个假的输入框
2、使用一个"隐藏"的输入框,其实我们的文本还是输入在这个文本框的
3、根据文本框的文本,进行截取填充到每一个输入框中
主要注意的是,这里的“隐藏”文本框不能将input元素设置hidden,这样的话就获取不到文本框的值了,让他挡在我们展示输入框的地方就好了
css参考:
.overlay-input {
border: 0;
outline: 0;
position: absolute;
top: 0;
height: 40px;
width: 200%;
margin-left: -100%;
opacity: 0;
}
这里是使用vue实现的,具体的代码:
<template>
<div style="position: relative">
<input :type="inputType" :maxlength="textNumber" ref="textInput"
v-model="text"
@compositionstart="isIME=true"
@compositionend="IME_End"
class="overlay-input"/>
<ul class="text-wrap">
<li v-for="(n,index) in textNumber">
<input
:type="inputType" maxlength="1"
:ref="'input'+index"
/>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "TextAutoFocus",
props: {
textNumber: {
required: true,
type: Number,
default: 4
},
inputType: {
type: String,
default: 'text'
}
},
data() {
return {
isIME: false,
text: ''
}
},
watch: {
text(newVal, oldVal) {
if (!this.isIME) {
var strs = this.text.split('');
for (let i = 0; i < this.textNumber; i++) {
this.$refs['input' + i][0].value = strs[i] || '';
}
}
},
},
methods: {
IME_End() {
this.isIME = false;
},
input() {
this.$refs.textInput.focus();
}
}
}
</script>
<style scoped>
.overlay-input {
border: 0;
outline: 0;
position: absolute;
top: 0;
height: 40px;
width: 200%;
margin-left: -100%;
opacity: 0;
}
.text-wrap {
list-style: none;
}
.text-wrap li {
display: inline-block;
width: 35px;
height: 35px;
border: 1px solid skyblue;
border-right: 0;
}
.text-wrap li input {
height: 35px;
width: 35px;
border: 0;
background: none;
text-align: center;
font-size: 16px;
}
.text-wrap li:last-child {
border: 1px solid skyblue;
}
</style>
目前功能比较单一,知道这个思路就好了。
还有就是检测输入法状态,利用了compositionstart和compositionend这两个事件,
不然输入法输入zhangsan,监听的时候还未感知到是否输入完毕,会触发很多次相应处理 z,zh,zha...