需求是年前提的,因为不着急,就一直搁置着,放在最后弄
年前快放假的时候,抽空搜了下,在表单内实现上下箭头移动聚焦的没搜到,倒是有在表格内如何实现的,但没有细细研究
今天早上,突然就想起这个需求,想应该如何实现之类的,为此还特意画了草稿
ps:写写画画真的有助于直观面对问题,思路是从画图开始才有的
一、初步思路
假设表单有三列
以E举例,按上箭头就要聚焦到B输入框内,
按下箭头就要聚焦到H输入框内,
按左箭头就要聚焦到D输入框内,
按右箭头就要聚焦到F输入框内
如果索引从0开始,E的索引是4,对应的B 是1,H 是7,D是3,F是5
根据规律不难发现,左右箭头的关系是最简单的,在当前索引的基础上减1和加1的关系
也就是说如果我要向左,就要拿到当前索引-1项的输入框,并添加聚集事件,向右亦是如此
上下箭头的关系其实也简单,在当前索引的基础上减3和加3的关系
向上就要拿到当前索引-3项的输入框,并添加聚集事件,向下亦是如此
多观察几组会发现,左右一直都是当前索引加1和减1,而上下是当前索引加列数和减列数,
比如:有3列就加3减3,有4列就加4减4,依此类推
初步思路有了,还需要有步骤的进阶思路
二、进阶思路
我们要给所有的输入框加一个公共类名,然后给每一列加一个单独的类名
公共类名是为了获取所有输入框所在的数组,单独的类名是为了计算当前索引
我们需要拿到event事件,拿到绑在input上的类名,判断属于哪一列,为了计算当前索引
我们要手动加行索引和列数,为了计算当前索引和移动后索引
每次触发事件的时候,要拿到当前项的索引,在当前索引的基础上,根据条件算出移动后的索引并触发聚焦事件
三、具体实现
1、在表单上给所有输入框加类名和事件,5是第五行(第一行索引0,以此类推),2是第二列
<el-form-item :label="form.label" prop="updateName" >
<el-input
v-model="form.updateName"
@keyup.native="keyDown($event, 5, 2)"
class="form_input form_input_left"
/>
</el-form-item>
<el-form-item :label="form.label" prop="updateTime" >
<el-input
v-model="form.updateTime"
@keyup.native="keyDown($event, 5, 2)"
class="form_input form_input_right"
/>
</el-form-item>
2、拿到event事件,行索引和列数后
keyDown(ev, index, col) {
let newIndex
//通过ev 获取 当前input 名称 用于判断属于哪列
let className = ev.target.offsetParent.className
// 当前项索引
if (className.indexOf('form_input_left') != -1) {
newIndex = index * col
} else if (className.indexOf('form_input_right') != -1) {
newIndex = index * col + 1
}
let input_left = document.getElementsByClassName('form_input_left')
let input_right = document.getElementsByClassName('form_input_right')
let inputAll = document.querySelectorAll('.form_input input')
//键盘按键判断:左箭头-37;上箭头-38;右箭头-39;下箭头-40
//按左箭头
if (ev && ev.keyCode == 37) {
newIndex -= 1
}
// 按右箭头
else if (ev && ev.keyCode == 39) {
newIndex += 1
}
// 按上箭头
else if (ev && ev.keyCode == 38) {
newIndex -= col
}
// 按下箭头
else {
newIndex += col
}
if (inputAll[newIndex]) {
if (inputAll[newIndex].disabled) return this.$message.warning('禁用项,不可选择')
inputAll[newIndex].focus()
}
},