一:首先从antd中引入table,基于onRowClick监听事件
import { Table } from 'antd'
<Table
columns={this.columns}
dataSource={datalist.toJS()}
onRowClick={this.handleKeydown} // 具体键盘操作事件
/>
二:handleKeydown的具体事件执行
handleKeydown = (record, index, event) => {
// 类型为INPUT类型时监听
if (event.target.tagName === 'INPUT') {
// 根据当前获取焦点的input,找到最近的tr标签
const currentTr = event.target.parentElement.closest('tr')
// 根据当前获取焦点的input,找到最近的td标签
const currentTd = event.target.parentElement.closest('td')
// 根据当前获取焦点的input,找到最近的table标签
const tableDom = event.target.parentElement.closest('table')
// 通过table找到tbody
const tbodyDom = tableDom.querySelector('tbody')
// 获取tr整个长度
const trLength = currentTr.children.length - 1
// 获取td整个长度
const tdLength = this.props.datalist.size - 1
let colVal = Array.prototype.indexOf.call(currentTr.children, currentTd) // 列
let rowVal = index // 行
tableDom.onkeydown = (e) => {
const codeVal = e.keyCode
if (codeVal === 37) {
colVal--
// 如果找不到当前input循环找下一列input
const { newColVal } = this.whileAdd('colVal', 'reduce', tbodyDom, rowVal, colVal)
colVal = (newColVal < 0 ? 0 : newColVal)
} else if (codeVal === 38) {
rowVal--
// 如果找不到当前input循环找下一行input
const { newRowVal } = this.whileAdd('rowVal', 'reduce', tbodyDom, rowVal, colVal)
rowVal = (newRowVal < 0 ? 0 : newRowVal)
} else if (codeVal === 39) {
colVal++
const { newColVal } = this.whileAdd('colVal', 'add', tbodyDom, rowVal, colVal)
colVal = (newColVal > trLength ? trLength : newColVal)
} else if (codeVal === 40) {
rowVal++
const { newRowVal } = this.whileAdd('rowVal', 'add', tbodyDom, rowVal, colVal)
rowVal = (newRowVal > tdLength ? tdLength : newRowVal)
}
// 执行获取焦点,并且文本框文字被选中操作
this.handleMove(tbodyDom, rowVal, colVal)
}
}
}
三:whileAdd的具体事件执行
whileAdd = (type, operateType, tbodyDom, rowVal, colVal) => {
const tdDom = tbodyDom.childNodes[rowVal] && tbodyDom.childNodes[rowVal].childNodes[colVal]
const inputDom = tdDom ? tdDom.querySelector('input') : 'noTdDom'
if (!inputDom) {
if (operateType === 'reduce') {
(type === 'rowVal') ? (rowVal--) : colVal--
} else {
(type === 'rowVal') ? rowVal++ : colVal++
}
// 递归执行
this.whileAdd(type, operateType, tbodyDom, rowVal, colVal)
}
return {
newRowVal: rowVal,
newColVal: colVal,
}
}
四:handleMove的具体事件执行
handleMove = (tbodyDom, rowVal, colVal) => {
const tdDom = tbodyDom.childNodes[rowVal].childNodes[colVal]
const inputDom = tdDom.querySelector('input')
if (inputDom) {
// 由于dom渲染有时间差,用setTimeout包裹,等渲染完执行获取焦点和select
setTimeout(() => {
inputDom.focus()
inputDom.select()
}, 0);
}
}