Javascript:使用箭头键导航表格输入

2024-05-07

我正在为客户制作 HTML 成绩册。我使用 PHP 生成成绩册,然后输出一个 HTML 表,如下例所示。每个<td>包含一个带有<input>以便老师输入学生的分数。

这就是我想要实现的目标:如何才能让老师可以使用键盘上的箭头键在成绩册内导航? IE:教师应该能够单击单元格,输入成绩,然后按左/右/上/下箭头键移动到适当的输入并输入下一个成绩。

我在这里看到了很多关于如何使用 javascript 来完成此任务的示例,以突出显示不同的内容<td>单元格,但我不知道如何让老师用箭头键导航输入。任何建议将不胜感激。

   body {
     margin: 0;
     position: absolute;
     top: 105px; left: 0px;
     width: 100%;
     height: calc(100vh - 105px);
     background-color: #FCFCFC;
     display: grid;
     grid-template-rows: 1fr;
     grid-template-areas:
       "master"}

   .master {
     grid-area: master;
     overflow-x: scroll;}

   table {border-collapse: collapse}

   th, td {
     background-color: white;
     max-width: 110px;
     border: 1px solid lightgray;}

   th {overflow: hidden;}

  thead{
    top: 0;
    position: sticky;
    z-index: 1;}

  tr td:nth-child(1),
  tr th:nth-child(1){
    position: sticky;
    left: 0;}

   thead th.navigator { /* Top left cell with navigation controls */
     padding: 10px;
     z-index: 3;}

   tr td:first-child, tr td:nth-child(2) { /* First two columns of each row */
     white-space: nowrap;
     max-width: fit-content !important;}

   td input {
     border: none;
     outline: none;
     text-align: center;
     max-width: 80%;
     font-size: 18px;
     padding: 6px 0px;
     cursor: cell;}

   th select {
     outline: none;
     -webkit-appearance: none;
     padding: 8px 12px;
     box-sizing: border-box;
     border-radius: 8px;
     width: 100%;
     border: 1px solid lightgray}

  tr:focus-within td:not(.gray) {background-color: #E9DCF9}
  tr:focus-within td:not(.gray) input {background-color: #E9DCF9}

  .due {
    font-size: 11px;
    color: darkgray;}

   .assign {padding: 20px}
   .assign span {
     cursor: pointer;
     font-size: 15px;
     overflow: hidden;
     color: #581F98}

   .avg {padding: 10px}

   .studentInfo {
     display: flex;
     align-items: center;
     margin: 10px 12px 10px 6px;}

   .studentInfo img {
     width: 25px;
     margin-right: 10px;
     clip-path: circle();}

   .red {background-color: red;}
   .gray, .gray input {background-color: #F2F2F2;}

  .score {
    display: flex;
    justify-content: center;
    align-items: center;}
        <table>
          <thead>
            <tr>
              <th class='navigator' colspan='2' rowspan='4'>
                <form method='GET'>
                  <select name='subID' onchange='this.form.submit()'>
                    <option value='1' >Reading</option>
                    <option value='2' >Social Studies</option>
                  </select>
                  <select name='week' onchange='this.form.submit()' disabled>
                    <option value='all'>Entire Quarter</option>
                  </select>
                </form>
              </th>
              <tr>
                <th class='due'><span title='Monday'>10/11</span> to <span title='Wednesday'>10/13</span></th>
                <th class='due'><span title='Wednesday'>10/20</span> to <span title='Friday'>10/22</span></th>
                <th class='due'><span title='Monday'>10/18</span> to <span title='Friday'>10/22</span></th>
                <th class='due'><span title='Wednesday'>10/20</span> to <span title='Friday'>10/22</span></th>
              </tr>
              <tr>
                <th class='assign'>
                  <span title='Assignment ID: 130' onclick='assignInfo("130");'>???? Quiz</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 146' onclick='assignInfo("146");'>???? Homework</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 145' onclick='assignInfo("145");'>???? Test</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 147' onclick='assignInfo("147");'>✏️ Project</span>
                </th>
            </tr>
            <tr>
              <th class='avg gray'><span title='9.111/10'>91%</span></th>
              <th class='avg gray'><span title='8.672/10'>87%</span></th>
              <th class='avg gray'><span title='4.348/5'>87%</span></th>
              <th class='avg gray'><span title='8.007/10'>80%</span></th>
            </tr>
          </thead>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 11'><img src='../../resources/pics/students/11.jpg'></span>
                <span>John Doe</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='11' title='97.5/110'>89%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='11' data-workID='7280' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='11' data-workID='7282' data-curScore='9' value='9'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='11' data-workID='7340' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='11' data-workID='7280' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 12'><img src='../../resources/pics/students/12.jpg'></span>
                <span>Jane Doe</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='12' title='97.5/110'>69%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='12' data-workID='7250' data-curScore='6' value='6'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='12' data-workID='7211' data-curScore='9' value='9'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='12' data-workID='7110' data-curScore='4' value='4'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='12' data-workID='7233' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 13'><img src='../../resources/pics/students/13.jpg'></span>
                <span>Sally Martin</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='13' title='97.5/110'>100%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='13' data-workID='6250' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='13' data-workID='6211' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='13' data-workID='7610' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='13' data-workID='7933' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
        </table>

它并不完美,但它应该为您提供一个起点。您必须添加一些错误处理并处理边缘情况。

document.addEventListener( 'keydown', ( event ) => {

  const currentInput = document.activeElement;
  const currentTd = currentInput.parentNode.parentNode;
  const currentTr = currentTd.parentNode;
  const index = Array.from(currentTr.children).indexOf(currentTd);

  switch (event.key) {
    case "ArrowLeft":
        // Left pressed
        currentTd.previousElementSibling.getElementsByTagName('input')[0].focus();
        break;
    case "ArrowRight":
        // Right pressed
        currentTd.nextElementSibling.getElementsByTagName('input')[0].focus();
        break;
    case "ArrowUp":
        // Up pressed
        Array.from( currentTr.previousElementSibling.children )[index].getElementsByTagName('input')[0].focus();
        break;
    case "ArrowDown":
        // Down pressed
        Array.from( currentTr.nextElementSibling.children )[index].getElementsByTagName('input')[0].focus();
        break;
  }
} )
body {
     margin: 0;
     position: absolute;
     top: 105px; left: 0px;
     width: 100%;
     height: calc(100vh - 105px);
     background-color: #FCFCFC;
     display: grid;
     grid-template-rows: 1fr;
     grid-template-areas:
       "master"}

   .master {
     grid-area: master;
     overflow-x: scroll;}

   table {border-collapse: collapse}

   th, td {
     background-color: white;
     max-width: 110px;
     border: 1px solid lightgray;}

   th {overflow: hidden;}

  thead{
    top: 0;
    position: sticky;
    z-index: 1;}

  tr td:nth-child(1),
  tr th:nth-child(1){
    position: sticky;
    left: 0;}

   thead th.navigator { /* Top left cell with navigation controls */
     padding: 10px;
     z-index: 3;}

   tr td:first-child, tr td:nth-child(2) { /* First two columns of each row */
     white-space: nowrap;
     max-width: fit-content !important;}

   td input {
     border: none;
     outline: none;
     text-align: center;
     max-width: 80%;
     font-size: 18px;
     padding: 6px 0px;
     cursor: cell;}

   th select {
     outline: none;
     -webkit-appearance: none;
     padding: 8px 12px;
     box-sizing: border-box;
     border-radius: 8px;
     width: 100%;
     border: 1px solid lightgray}

  tr:focus-within td:not(.gray) {background-color: #E9DCF9}
  tr:focus-within td:not(.gray) input {background-color: #E9DCF9}

  .due {
    font-size: 11px;
    color: darkgray;}

   .assign {padding: 20px}
   .assign span {
     cursor: pointer;
     font-size: 15px;
     overflow: hidden;
     color: #581F98}

   .avg {padding: 10px}

   .studentInfo {
     display: flex;
     align-items: center;
     margin: 10px 12px 10px 6px;}

   .studentInfo img {
     width: 25px;
     margin-right: 10px;
     clip-path: circle();}

   .red {background-color: red;}
   .gray, .gray input {background-color: #F2F2F2;}

  .score {
    display: flex;
    justify-content: center;
    align-items: center;}
<table>
          <thead>
            <tr>
              <th class='navigator' colspan='2' rowspan='4'>
                <form method='GET'>
                  <select name='subID' onchange='this.form.submit()'>
                    <option value='1' >Reading</option>
                    <option value='2' >Social Studies</option>
                  </select>
                  <select name='week' onchange='this.form.submit()' disabled>
                    <option value='all'>Entire Quarter</option>
                  </select>
                </form>
              </th>
              <tr>
                <th class='due'><span title='Monday'>10/11</span> to <span title='Wednesday'>10/13</span></th>
                <th class='due'><span title='Wednesday'>10/20</span> to <span title='Friday'>10/22</span></th>
                <th class='due'><span title='Monday'>10/18</span> to <span title='Friday'>10/22</span></th>
                <th class='due'><span title='Wednesday'>10/20</span> to <span title='Friday'>10/22</span></th>
              </tr>
              <tr>
                <th class='assign'>
                  <span title='Assignment ID: 130' onclick='assignInfo("130");'>???? Quiz</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 146' onclick='assignInfo("146");'>???? Homework</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 145' onclick='assignInfo("145");'>???? Test</span>
                </th>
                <th class='assign'>
                  <span title='Assignment ID: 147' onclick='assignInfo("147");'>✏️ Project</span>
                </th>
            </tr>
            <tr>
              <th class='avg gray'><span title='9.111/10'>91%</span></th>
              <th class='avg gray'><span title='8.672/10'>87%</span></th>
              <th class='avg gray'><span title='4.348/5'>87%</span></th>
              <th class='avg gray'><span title='8.007/10'>80%</span></th>
            </tr>
          </thead>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 11'><img src='../../resources/pics/students/11.jpg'></span>
                <span>John Doe</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='11' title='97.5/110'>89%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='11' data-workID='7280' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='11' data-workID='7282' data-curScore='9' value='9'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='11' data-workID='7340' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='11' data-workID='7280' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 12'><img src='../../resources/pics/students/12.jpg'></span>
                <span>Jane Doe</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='12' title='97.5/110'>69%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='12' data-workID='7250' data-curScore='6' value='6'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='12' data-workID='7211' data-curScore='9' value='9'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='12' data-workID='7110' data-curScore='4' value='4'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='12' data-workID='7233' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
          <tr>
            <td>
              <div class='studentInfo'>
                <span title='Student ID: 13'><img src='../../resources/pics/students/13.jpg'></span>
                <span>Sally Martin</span>
              </div>
            </td>
            <td class='avg gray'>
              <span data-studentAvg='13' title='97.5/110'>100%</span>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='13' data-workID='6250' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='131' data-usid='13' data-workID='6211' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='132' data-usid='13' data-workID='7610' data-curScore='10' value='10'>
              </div>
            </td>
            <td>
              <div class='score'>
                <input type='text' data-assID='130' data-usid='13' data-workID='7933' data-curScore='10' value='10'>
              </div>
            </td>
          </tr>
        </table>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript:使用箭头键导航表格输入 的相关文章

随机推荐

  • 如果h2表不存在则插入

    我正在使用H2 我想将一个值插入到表中 如果它不存在 我使用以下命令创建表 CREATE TABLE IF NOT EXISTS types type VARCHAR 15 NOT NULL UNIQUE 我想做一些类似的事情 REPLAC
  • 从 CUDA 设备写入输出文件

    我是 CUDA 编程的新手 正在将 C 代码重写为并行 CUDA 新代码 有没有一种方法可以直接从设备写入输出数据文件 而无需将数组从设备复制到主机 我假设如果cuPrintf存在 一定有地方可以写一个cuFprintf 抱歉 如果答案已经
  • 调试 Android 库中的本机代码

    我的工作空间布局是 ApplicationLibrary AndroidManifest xml jni libs src Application AndroidManifest xml ant properties 如何在 Eclipse
  • Excel Active-X 按钮无法单击

    我有一个在 Excel 中应该可以点击的按钮 当我尝试单击它时 什么也没有发生 我注意到 如果我单击并按住右下角的鼠标 则会出现第二个按钮 这种情况过去发生过 当我移动鼠标单击该按钮时 我可以单击 一切都会正常 但这一次 当我移动鼠标时 按
  • 更新行时获取电子邮件用户值

    我和我的团队有电子表格 当他们更新行 基于他们使用的帐户 时 如何 自动 获取电子邮件用户值 因此 每次他们更新 任务 列时 电子邮件 列都会自动更新 就像下表一样电子表格 https i stack imgur com lgDhF png
  • 如何在 Docker for Windows 中设置共享驱动器?

    如何在 Docker for Windows 中设置共享驱动器 我正在使用最新版本 18 Stable 和 Edge 我的设置屏幕如下所示 它缺少一些选项 如共享驱动器 高级和网络 如第二张图片所示 为什么我缺少这些选项 My settin
  • 如何在 ReactJs 中使用 Hooks useState 编写多行状态

    React 16 9 我知道这class component state class JustAnotherCounter extends Component state count 0 相当于使用Hooks useState functi
  • 在 dart 中,集合如何确定两个对象相等?

    我不明白集合如何确定两个对象何时相等 更具体一点 什么时候add集合的方法 确实添加了一个新对象 并且什么时候它不作用一个新对象 因为该对象已经在集合中 例如 我有以下类的对象 class Action final Function fun
  • iOS 安全性将带有密码的数据发送至服务器或从服务器发送数据

    我正在构建一个应用程序 需要在服务器执行任何操作之前从用户设备发送密码以在服务器上进行身份验证 事情是这样的 用户的手机上有一个纯文本密码 该密码也在服务器中以 bcrypt 二进制文件的形式存在 用户想要从数据库中获取某些内容 因此用户通
  • 使用 linux perf 工具测量应用程序的 FLOP

    我想使用 perf Linux 性能计数器子系统的新命令行接口命令 来测量某些应用程序执行的浮点和算术运算的数量 出于测试目的 我使用了我创建的一个简单的虚拟应用程序 请参见下文 因为我找不到任何为测量 FP 和整数运算而定义的 perf
  • GLSL 棋盘图案

    我想用跳棋来遮蔽四边形 f P 下限 Px 下限 Py mod2 我的四边形是 glBegin GL QUADS glVertex3f 0 0 0 0 glVertex3f 4 0 0 0 glVertex3f 4 4 0 0 glVert
  • x % 2 == 0 是什么意思? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我确信这是
  • Python:数百万个小文件的读写速度缓慢

    结论 看来 HDF5 是适合我的目的的方法 基本上 HDF5 是一种用于存储和管理数据的数据模型 库和文件格式 并且旨在处理令人难以置信的大量数据 它有一个名为 python tables 的 Python 模块 链接在下面的答案中 HDF
  • 第 n 个孩子没有响应课程 [重复]

    这个问题在这里已经有答案了 是否可以让 nth child 伪选择器与特定的类一起使用 看这个例子 http jsfiddle net fZGvH http jsfiddle net fZGvH 我想让第二个 DIV red 变成红色 但它
  • HttpServletRequest.getRemotePort() 在同一台机器上收到的每个 http 请求返回不同的端口?

    我需要识别注册到我的服务的客户端的远程 IP 和端口 此外 当客户端 Web 应用程序出现故障时 它会从我的 Web 服务中取消注册 我在用HttpServletRequest getRemoteAddress and HttpServle
  • 如何在C#中确定现有的oracle数据库连接?

    假设我使用正确的凭据调用以下方法 private bool Connect string username string password string CONNSTRING Provider MSDAORA Data Source ISD
  • Single.zip - 如何捕获失败的呼叫并继续其余的网络呼叫?

    我正在进行 5 个并行网络调用 模拟其中 4 个成功 其中 1 个失败 失败的调用使整个Single zip 失败 即使其他 4 个网络调用成功 我也无法获得它们的结果 如何处理单个失败的网络调用的错误Single zip 并获得成功者的结
  • 标头搜索路径给 Grabkit 带来麻烦

    我正在为 iPad 开发一个 iOS 6 应用程序 我使用一个名为 Grabkit 的存储库 我必须将其作为嵌套 子项目添加到我的项目中 为了使其工作 我必须在标题搜索路径中添加以下代码 TARGET BUILD DIR include G
  • 按行中的值选择 pandas 数据框中的列

    我有一个pandas DataFrame列太多 我想选择行中的值等于的所有列0 and 1 所有列的类型是int64我无法通过以下方式选择它们object或其他类型 我怎样才能做到这一点 IIUC 然后你可以使用isin http pand
  • Javascript:使用箭头键导航表格输入

    我正在为客户制作 HTML 成绩册 我使用 PHP 生成成绩册 然后输出一个 HTML 表 如下例所示 每个 td 包含一个带有 td