vue 模拟填空题方格输入(一个文字一个方格)
前言:用于APP、H5的答题功能。
当前题目的数据
currentQus:{
questionName: "举头望(),低头思()。" //标题
rightKey: "明月,故乡", //答案
userKey:"", //用户输入的答案
blankList:[] //绑定每一个格子的model,用于处理用户输入的答案
}
首先根据标题和答案,处理好格子数,以及每一个方格所在位置,绑定到model,用于页面渲染
/ 处理填空题标题 /
handleBlankTile(currentQus) {
const { questionName, rightKey } = currentQus
const nameList = questionName.split('()')
const rightKeys = rightKey ? rightKey.split(',') : []
blankNameList = []
blankList = []
let index = 1
nameList.forEach((el, i) => {
el.split('').map((txt) => {
blankNameList.push({ type: 'txt', content: txt })
})
if (i !== nameList.length - 1) {
const rightTxt = rightKeys[i]
blankNameList.push({
type: 'input',
content: rightTxt.split('').map((item) => {
blankList.push('')
return {
index: index++,
}
}),
})
}
})
return { blankNameList, blankList }
},
- blankNameList用于标题渲染,blankList的长度等于格子数用于绑定数据([’’,’’,’’,’’,])
- blankNameList打印结果如下:
将文字也分开是为了进行页面布局、换行
根据以上处理好的数据来渲染html代码
{
{ subItem.type !== ‘input’ ? subItem.content : ‘’ }}
判断用户是要输入还是删除,分以下几种情况
- 单文字输入直接将焦点转移到下一个输入框
- 删除将焦点转移到上一个输入框
- 多文字输入填充
- 拿到用户当前输入框所有文字集合数组
- 定位是从第几个框开始输入,
- 输入的文字字数和当前框到最后一个框的输入框数量的关系,是否超出等
- 将焦点放到最后一个文字所在的输入框
- 将文字赋值到blankList,更新视图 (不然有bug)
- 储存用户输入的答案
/* 填空题输入效果——输入框自动失焦以及转移到下个焦点 */
inputChange(e, iptI) {
this.$nextTick(() => {
const els = document.getElementsByClassName('inputVal')
switch (e.inputType) {
case 'insertText':
case 'insertFromPaste':
const str = els[iptI - 1].value
const strList = str.split('')
const strL = strList.length
const elsL = els.length
// alert(strL)
if (strL > 1) {
strList.map((item, i) => {
if (i < elsL - iptI + 1) {
els[iptI - 1 + i].value = item
this.$set(this.currentQus.blankList, iptI - 1 + i, item)
}
if (i === strL - 1) {
// 字数等于或大于空格数时焦点到最后一个空格
if (strL > elsL - iptI || strL === elsL - iptI) {
els[elsL - 1].focus()
} else {
els[iptI + i].focus()
}
}
})
} else {
if (str !== els.length) {
els[iptI].focus()
}
}
break
case 'deleteContentBackward':
if (iptI > 1) {
els[iptI - 2].focus()
}
break
}
this.getUserKey(this.currentIdx - 1) //保存用户答案
})
},
储存用户输入的填空题答案
getUserKey() {
const { type, rightKey } = this.currentQus
// 填空题答案处理
let startIdx = 0
const rightKeys = rightKey.split(',').map((txt) => {
const textLength = txt.length
const str = this.blankList
.slice(startIdx, startIdx + textLength)
.join('')
startIdx += textLength
return str
})
const flag = rightKeys.some((item) => {
return item
}) //是否有作答
this.currentQus.userKey = flag ? rightKeys.join(',') : ''
}
优化一下标题输入框
.unit-cell-input {
width: 21px;
height: 21px;
background: #dedee2;
display: inline-block;
margin: 0 4px;
text-align: center;
border: 1px solid transparent;
color: #5050de;
font-weight: 700; &:focus {
border: 1px solid #5656df;
}
}
}
.bank-title {
margin-bottom: 40px;
display: flex;
flex-wrap: wrap;
}
效果图如下
)
还没有评论,来说两句吧...