在vue项目中实现方向键切换输入框焦点的方法
首先用table
标签绘制一个表格出来,表格一共有7列,第一和第二列是写死的文本,不需要获取焦点,后五列是input
框,需要按方向键获取焦点并且选中文本,分两步来实现:
1.绑定focus
事件,input
框获得焦点后选中文本
2.绑定keyup
,键盘弹起后让下一个input
获得焦点
<table class="table">
<thead>
<tr>
<th>第一列</th>
<th>第二列</th>
<th>第三列</th>
<th>第四列</th>
<th>第五列</th>
<th>第六列</th>
<th>第七列</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in tableData" :key="index">
<td>{{item.date}}</td>
<td>{{item.name}}</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:0})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:1})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:2})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:3})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:4})"
/>
</td>
</tr>
</tbody>
</table>
js部分
focus
事件比较简单,一行代码
keyup
事件里的一些逻辑我已经在代码里注释了,直接看代码注释吧
methods: {
focus(event) {
event.currentTarget.select();
},
//键盘触发事件
keyup_({ ev, index, column, rank }) {
// index 第index行,column 所有input所在的总列数,rank input在第rank列
let newIndex;
//每一列
newIndex = index * column + rank;
let inputAll = [];
if (this.$el) {
inputAll = this.$el.querySelectorAll(".get-input");
}
//向上 =38
if (ev.keyCode == 38) {
//当焦点在第一行的时候 按向上的时候焦点要聚焦到前一列的最后一个
do {
if (newIndex >= 1 && newIndex <= column - 1) {
newIndex = newIndex + inputAll.length - column - 1;
} else {
newIndex -= column;
}
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//下 = 40
if (ev.keyCode == 40) {
//当newIndex 在最后一行的时候 焦点要聚焦到 下一列的第一个
do {
if (
newIndex >= inputAll.length - column &&
newIndex < inputAll.length - 1
) {
newIndex = (newIndex % column) + 1;
} else {
newIndex += column;
}
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//左 = 37
if (ev.keyCode == 37) {
do {
newIndex -= 1;
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//右 = 39
if (ev.keyCode == 39) {
do {
newIndex += 1;
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
},
},
完整代码、TableDemo.vue文件
// TableDemo.vue
<template>
<div>
<table class="table">
<thead>
<tr>
<th>第一列</th>
<th>第二列</th>
<th>第三列</th>
<th>第四列</th>
<th>第五列</th>
<th>第六列</th>
<th>第七列</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in tableData" :key="index">
<td>{{item.date}}</td>
<td>{{item.name}}</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:0})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:1})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:2})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:3})"
/>
</td>
<td>
<input
class="inp get-input"
@focus="focus($event)"
v-model="item.age"
type="text"
placeholder="请输入"
@keyup="keyup_({ev:$event,index:index,column:5,rank:4})"
/>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: "TableDemo",
data() {
return {
tableData: [
{
date: "1",
name: "王",
age: "1",
},
{
date: "2",
name: "王小",
age: "1",
},
{
date: "3",
name: "王小虎",
age: "1",
},
{
date: "4",
name: "王虎",
age: "1",
},
],
};
},
methods: {
focus(event) {
event.currentTarget.select();
},
//键盘触发事件
keyup_({ ev, index, column, rank }) {
// index 第index行,column 所有input所在的总列数,rank input在第rank列
let newIndex;
//每一列
newIndex = index * column + rank;
let inputAll = [];
if (this.$el) {
inputAll = this.$el.querySelectorAll(".get-input");
}
//向上 =38
if (ev.keyCode == 38) {
//当焦点在第一行的时候 按向上的时候焦点要聚焦到前一列的最后一个
do {
if (newIndex >= 1 && newIndex <= column - 1) {
newIndex = newIndex + inputAll.length - column - 1;
} else {
newIndex -= column;
}
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//下 = 40
if (ev.keyCode == 40) {
//当newIndex 在最后一行的时候 焦点要聚焦到 下一列的第一个
do {
if (
newIndex >= inputAll.length - column &&
newIndex < inputAll.length - 1
) {
newIndex = (newIndex % column) + 1;
} else {
newIndex += column;
}
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//左 = 37
if (ev.keyCode == 37) {
do {
newIndex -= 1;
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
//右 = 39
if (ev.keyCode == 39) {
do {
newIndex += 1;
} while (
inputAll[newIndex] &&
inputAll[newIndex].getAttribute("disabled")
//如果input是禁用状态,就会跳过禁用的input,到下一个
);
if (inputAll[newIndex]) {
inputAll[newIndex].focus();
}
}
},
},
};
</script>
<style>
.table {
width: 100%;
border: 1px solid #ccc;
border-collapse: collapse;
}
.table tr th,
.table tr td {
border: 1px solid #ccc;
padding: 10px;
}
.inp {
width: 100%;
height: 20px;
padding: 15px;
text-align: center;
outline: none;
border: 1px solid transparent;
background: transparent;
box-sizing: border-box;
}
input[type="text"]:focus {
border-bottom: 1px solid #1890ff;
}
</style>
看效果
a.gif总结
不断在学习,有不对的地方,欢迎指正。
网友评论