JS实现方向键切换输入框焦点的方法

2020-09-11  本文已影响0人  zhao_ran

在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

总结

不断在学习,有不对的地方,欢迎指正。

上一篇下一篇

猜你喜欢

热点阅读