练习牛客网笔试题--前端js--64-移动控制

这篇博客主要介绍了如何通过JavaScript实现一个功能,即在HTML表格中使用键盘上下左右箭头控制选中单元格的移动。当按下键盘上的上、下、左、右键时,当前选中的单元格会根据指定方向切换高亮,遵循在边界处的特殊移动规则,如在第一列往左移至最后一列,最后一列往右移至第一列等。示例代码展示了具体的实现逻辑。
摘要由CSDN通过智能技术生成

    // 描述

    // 界面中存在id=jsContainer的节点A,系统会随机生成id为jsLayout的 m行 x n列 表格(m >= 1, n >= 1),并随机选中一个td节点,请按照如下需求实现bind函数

    // 1、bind 函数为document绑定keydown事件,当系统触发上(键值38)下(键值40)左(键值37)右(键值39)按键时,请找到当前选中的td节点,并根据当前指令切换高亮节点,具体效果参考以下图片

    // 2、在第一列往左移动则到达最后一列;在最后一列往右移动则到达第一列;在第一行往上移动则到达最后一行;在最后一行往下移动则到达第一行;

    // 3、请不要手动调用bind函数

    // 4、当前界面为系统在节点A中生成 9 * 9 表格并随机选中一个td节点后的效果

    // 5、请不要手动修改html和css,请不要修改js中的事件绑定方式

    // 6、不要使用第三方插件

1.自己的练习

  <style>
    table.game {
      font-size: 14px;
      border-collapse: collapse;
      width: 100%;
      table-layout: fixed;
    }

    table.game td {
      border: 1px solid #e1e1e1;
      padding: 0;
      height: 30px;
      text-align: center;
    }

    table.game td.current {
      background: #1890ff;
    }
  </style>

  <div id="jsContainer">
    <table class="game">
        <tbody>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td class="current"></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
            <tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
        </tbody>
    </table>
</div>
    function bind() {
      // 获取元素节点
      var container = document.querySelector('#jsContainer')
      var current = container.querySelector('.current')
      // 表格的 行m 列n
      var m = container.querySelectorAll('tr')[0].querySelectorAll('td').length
      var n = container.querySelectorAll('tr').length

      document.onkeydown = event => {
        if (!event) return;
        var code = event.keyCode || '';
        if (!{ '37': 1, '38': 1, '39': 1, '40': 1 }[code]) return;
        event.preventDefault && event.preventDefault();

        // TODO: 请实现按键控制
        if (m > 1 && n > 1) {
          // 动态获取 current 横坐标 x 
          var current = container.querySelector('.current')
          var x = 0
          var preNode = current
          while (preNode.previousElementSibling) {
            x++
            preNode = preNode.previousElementSibling
          }

          if (code === 39) { // 右键
            if (current.nextElementSibling) {
              current.nextElementSibling.className = 'current'
            } else { // 跳到第一行
              current.parentElement.children[0].className = 'current'
            }
          } else if (code === 37) { // 左键
            if (current.previousElementSibling) {
              current.previousElementSibling.className = 'current'
            } else { // 跳到最后一行
              current.parentElement.children[m - 1].className = 'current'
            }
          }
          else if (code === 38) { // 上键
            var current = container.querySelector('.current')
            if (current.parentElement.previousElementSibling) {
              current.parentElement.previousElementSibling.children[x].className = 'current'
            } else {
              current.parentElement.parentNode.children[n - 1].children[x].className = 'current'
            }
          } else if (code === 40) { // 下键
            var current = container.querySelector('.current')
            if (current.parentElement.nextElementSibling) {
              current.parentElement.nextElementSibling.children[x].className = 'current'
            } else {
              current.parentElement.parentElement.children[0].children[x].className = 'current'
            }
          }
          current.className = ''
        }
      };
    }

2.题解

    function bind1() {
      document.onkeydown = event => {
        if (!event) return;
        var code = event.keyCode || '';
        if (!{ '37': 1, '38': 1, '39': 1, '40': 1 }[code]) {
          return;
        }
        event.preventDefault && event.preventDefault();
        // TODO: 请实现按键控制
        var tr = document.querySelectorAll('tr'); // 所有行
        var mL = tr.length; // 行数
        var td = document.querySelectorAll('tr:first-of-type td'); // 第一行
        var nL = td.length; // 第一行有多少列
        var tdAll = document.querySelectorAll('td'); // 所有格子
        var temp;
        for (var i = 0; i < tdAll.length; i++) {
          if (tdAll[i].className == 'current') {
            temp = i; // 记录当前选中元素的下标
            tdAll[i].className = ''; // 去除当前选中元素的样式
            break;
          }
        }
        var row = parseInt(temp / nL) // 第几行,从0起
        var col = temp % nL
        if (code == '37') { // 左
          // td:nth-of-type()第一个元素从1开始,所以不能直接用行列的值计算
          if (col == '0') { // 如果在第一列往左移动则到达最后一列
            tr[row].querySelector('td:nth-of-type(' + Number(nL) + ')').className = 'current'
          } else { // 否则行不变,列-1
            tr[row].querySelector('td:nth-of-type(' + Number(col) + ')').className = 'current'
          }
        } else if (code == '39') { // 右
          if (col == nL - 1) { // 如果在最后一列往右移动则到达第一列
            tr[row].querySelector('td:nth-of-type(1)').className = 'current'
          } else { // 否则行不变,列+1
            tr[row].querySelector('td:nth-of-type(' + Number(col + 2) + ')').className = 'current'
          }
        } else if (code == '38') { // 上
          if (row == '0') { // 如果在第一行往上移动则到达最后一行
            tr[mL - 1].querySelector('td:nth-of-type(' + Number(col + 1) + ')').className = 'current'
          } else { // 否则列不变,行-1
            tr[row - 1].querySelector('td:nth-of-type(' + Number(col + 1) + ')').className = 'current'
          }
        } else if (code == '40') { // 下
          if (row == mL - 1) { // 如果在最后一行往下移动则到达第一行
            tr[0].querySelector('td:nth-of-type(' + Number(col + 1) + ')').className = 'current'
          } else { // 否则列不变,行+1
            tr[row + 1].querySelector('td:nth-of-type(' + Number(col + 1) + ')').className = 'current'
          }
        }
      };
    }
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值