【问题标题】:Moving focus to the next input element将焦点移至下一个输入元素
【发布时间】:2021-09-28 16:54:42
【问题描述】:

我想将焦点移到下一个输入元素,但不知道下一个元素使用的是什么TAB

背景
我有一张桌子,而且我在屏幕上的空间很有限。 该表中的一列有一个文本字段,其中包含的文本可能超出该列的宽度。为了让用户能够输入文本并同时查看所有文本而无需在输入字段中滚动,我需要放大/加宽输入字段。 现在这种放大只会在输入字段接收到焦点时发生,当焦点移动到另一个输入元素时它应该缩小。
但是:我不想简单地放大包含输入字段的列,因为这会在接收和失去对所述输入字段的焦点时不断重新呈现整个表格,这对用户来说非常丑陋和混乱。

到目前为止我的解决方案
当接收到要放大的输入元素的onfocus 事件时,我 将该元素的包含 TD 的 colspan 设置为某个值 X (X 是该 TD 应放大的列数),我为 X - 1 TD 设置 display: none 在包含 TD 的同一 TR 右侧具有焦点的输入元素。
当我收到onblur 事件时,我将恢复所有这些。那是带有输入元素的 TD,它现在获得了 colspan=1,并且包含该输入字段的 TD 右侧的下一个 X-1 TD 设置为 display: table-cell

问题
在重新渲染方面,上述所有工作都按预期工作。那就是只有一点点“跳跃”(因为没有更好的词)。但是,焦点不会移动到“下一个”输入元素,该元素将与刚刚获得焦点的输入字段相邻并且现在再次可见,但它会移动到第一个包含输入字段的 TD隐藏。

示例
让我们假设一个包含 5 列和 3 行的表,其中每个 TD 包含一个输入字段。
标记为 A-E 的列和标记为 1-3 的行。
所有列的宽度都相同,均为 20%。
A 列应该放大具有焦点的输入字段的一个 TD。
所以 A2 接收焦点并设置 colspan=3 然后 B2 和 C2 设置为 display: none
一旦 A2 的输入字段收到 onblur 事件,所有内容都将被还原。
A2 colspan=1 和 B2 和 C2 display: table-cell。 之后 D2 有了焦点,这就是我的问题。

方法
我明白我可以是一个矩阵,引用所有输入元素,然后是 setFocus 相应地。然而,这是我非常不喜欢的很多布线,而且很可能它会很脆弱。
最简单的方法是,如果我能以某种方式“重新计算”已经包含下一个焦点目标的模糊事件。显然,对于“计算”目标,它不使用任何隐藏元素。
另一种选择是,如果我可以简单地发出类似move the focus 2 elements back 的命令。
第三种选择是以某种方式从表格/TD 中提取焦点的输入字段并覆盖表格本身。我试图在这个问题How to increase a div DIV 中解释这一点,但我还没有找到合适的魔法 CSS 词来做到这一点。

【问题讨论】:

  • 能否添加 ("minimal reproducible example") 代码来重现您的问题?我认为操纵colspan 属性可能不是可行的方法,数据是真正的表格,还是您试图利用<table> 进行布局? CSS Grid 是否更适合,或者是一种列表形式,嵌套或其他形式?

标签: javascript html css


【解决方案1】:

我相信下一个输入没有得到焦点的原因是由于事件的顺序。当您在输入和点击选项卡中时,模糊事件发生在字段失去焦点之后。这意味着其他一些输入在模糊事件发生之前获得了焦点。由于您无法专注于隐藏的输入,因此焦点会转移到下一个可见的输入。

那你能做什么?好吧,你不能改变事件的顺序。但也许你可以改变你的整体方法。与其做所有表格布局的转换,不如只创建一个新输入,将其绝对定位在与需要增长的输入相同的单元格中。这将消除所有的跳跃。另外,如果您将绝对定位的输入放置在初始输入之后,[Tab]-ing out 将自动转到下一个字段。

td{
  width:200px;
  position:relative;
}
input:focus{
  border:2px solid red;
}
.long{
  position:absolute;
  top:0;
  left:0;
  width:300px;
  z-index:1;
}
<table border = "1">
  <tr>
    <td>
      <input type = "text" value = "text here">
    </td>
    <td>
      <input type = "text" value = "other field" />
    </td>
  </tr>
  <tr>
    <td>
      <input type = "text" value = "text here">
      <input type = "text" value = "long text here" class = "long" />
    </td>
    <td>
      <input type = "text" value = "other field" />
    </td>
  </tr>
</table>

注意,当长输入获得焦点,然后跳出时,下一列中的输入获得焦点。

【讨论】:

    【解决方案2】:

    感谢上面@qausipickle 的启发 我想出了这个解决方案

    td{
      position:relative;
    }
    input:focus{
      border:2px solid red;
    }
    input:focus.long{
      position:absolute;
      top:0;
      left:0;
      width:300px;
      z-index:1;
    }
      <table border = "1">
          <tr>
             <td>
                 <input type = "text" value = "first long text" class="long">
             </td>
             <td>
                 <input type = "text" value = "other field" />
             </td>
          </tr>
          <tr>
              <td>
                   <input 
                        type = "text" 
                        value = "second long text" 
                        class = "long" />
              </td>
              <td>
                  <input type = "text" value = "other field" />
              </td>
          </tr>
      </table>

    【讨论】:

      猜你喜欢
      • 2011-01-28
      • 2023-03-22
      • 1970-01-01
      • 2020-04-02
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多