需求说明:
实现键盘上下键控制聚焦到列表行某个单元格,高亮显示当前聚焦行并编辑单元格
实现思路:
利用keyup事件监听键盘事件,给待聚焦单元格绑定keyup事件,并动态绑定类名(用下标作为类名,以便后续可通过下标类名找到对应dom元素,实现聚焦);
【下键】:自动聚焦下一行,如果当前行为列表末行时,聚焦回到首行;
【上键】:自动聚焦上一行,如果当前行为列表首行时,聚焦回到末行。
具体实现:
方法一:keyUp方法绑定事件
// 步骤一 实现高亮及聚焦逻辑
handleKeyUp(event, row) {
this.$refs.ruleTable.$refs.elTable.setCurrentRow() // 取消高亮
let nextIndex = 0 // 下一次聚焦行下标
if (event.keyCode === 38) {
// 键盘->上箭头
if (row.tableIndex - 1 < 0) {
// 首行按上键时,聚焦到列表最后一行
nextIndex = this.tableData.length - 1
} else {
nextIndex = row.tableIndex - 1
}
} else {
// 键盘->下箭头
if (row.tableIndex + 1 > this.tableData.length || row.tableIndex + 1 === this.tableData.length) {
// 末行按上键时,聚焦到列表第一行
nextIndex = 0
} else {
nextIndex = row.tableIndex + 1
}
}
this.$nextTick(() => {
// 高亮当前聚焦行
this.$refs.ruleTable.$refs.elTable.setCurrentRow(this.tableData[nextIndex], true)
})
// 获取聚焦元素
const focusDoms = document.getElementsByClassName(`keyUp${nextIndex}`)
// 找到聚焦元素的input子节点
const lastDom = focusDoms[0]?.querySelector('input')
lastDom.focus()
}
}
// 步骤二 给对应单元格绑定键盘事件及动态绑定类名
<el-input
:class="'keyUp' + $index"
v-model="row.goodName"
@keyup.up.native="event => handleKeyUp(event, row)"
@keyup.down.native="event => handleKeyUp(event, row)"
></el-input>
方法二:动态指令
Vue.directive('keyUp', {
inserted(el, binding) {
document.onkeyup = function (event) {
const row = binding.value.row
const tableData = binding.value.tableData
let nextIndex = 0 // 下一次聚焦行下标
if (event.keyCode === 38) {
// 上箭头
if (row.tableIndex - 1 < 0) {
// 首行按上键时,聚焦到列表最后一行
nextIndex = tableData.length - 1
} else {
nextIndex = row.tableIndex - 1
}
} else {
// 下箭头
if (row.tableIndex + 1 > tableData.length || row.tableIndex + 1 === tableData.length) {
// 末行按上键时,聚焦到列表第一行
nextIndex = 0
} else {
nextIndex = row.tableIndex + 1
}
}
// 获取聚焦元素
const focusDoms = document.getElementsByClassName(`keyUp${nextIndex}`)
// 找到聚焦元素的input子节点
const lastDom = focusDoms[0]?.querySelector('input')
lastDom.focus()
}
}
})