键盘焦点tabindex

@whizbz11 2018-12-14 15:36:46发表于 iuap-design/blog

outline 在访问一个表单页面,当tab键时,浏览器会自动定位到第一个输入框,再按tab时,会到下一个输入框。如果想按tab键自动使一个tree组件或者下拉框组件获取焦点,该怎么办呢?这时tabindex就出场了。这篇文章主要聊聊tabindex的使用,以及在键盘导航。

tabindex内容

tabindex 属性用于管理键盘焦点,决定元素是否能被选中,以及按下 tab 键过程中被选中的顺序,使用得当能够极大的提高应用的易用性.tabindex设置成-1,0,1+有什么区别?

tabIndex值 内容说明
-1 该元素就变成可由代码获取焦点,但其本身并不在 tab 键序列表中。也就是说,在按下 tab 键时,该元素不能获取到焦点,但是可以通过代码来获取到焦点。(eg:element.focus()方法)
0 元素的 tab 键序与其在源码中的顺序一致。默认情况下,如果元素本身是可获取焦点的就没有必要设置 tabindex 属性。但,如果你想让一个不能获取焦点的元素,比如
,也被包含在 tab 键序列表中,那么设置 tabindex = 0 就可以使这些元素按其在源码中的顺序出现在 tab 键序中。
1+ tabindex 值决定了元素的tab顺序:通常这些带有正数值的tabindex元素会排在tabindex="0"和原生可以tabable的元素前面;特别指出的是值越小越排在前面(举个例子,tabindex="7" 会排在tabindex="11"前面)

下面来个列子说明下

 <label for="username">Username:</label>
  <input type="text" id="username" tabindex="3">
  <label for="password">Password:</label>
  <input type="password" id="password" tabindex="1">
  <input type="submit" value="Log in" tabindex="2">
  <button >按钮</button>  

大家来猜猜连续按tab时,焦点的顺序。显示password-》submit-》username-》button按钮。

失效控件

当一个自定义控件变成失效(disabled)状态时,通过设置 tabindex="-1" 把它从 tab 序列里面移除。注意在一个组合组件里面失效状态的子项(比如菜单控件里面某一个菜单项)应该在方向键的响应事件里面跳过它不让 focus 中。
####控件中管理focus
当用户从一个组件 tab 离开之后 focus 回来,焦点应该回到离开之时正被 focus 中的元素上,比如某个树节点或者网格单元. 有两种办法完成这一点:

  • 流动 tabindex: 通过编程移动 focus
  • aria-activedescendent: 管理一个“虚拟” focus
方法 1: 流动 tabindex

在被 focus 中元素上设置 tabindex 为 "0",这样可以保证在用户在 tab 离开又返回后仍然选中组合组件中之前被选中的那项。注意在更改 tabindex 为“0”同时需要把之前选中过的那项设置tabindex="-1"。这个方法包含在键盘事件里面通过程序移动焦点以及更改 tabindex 到当前焦点中的那项上。需要做以下几步:

在每个元素上绑定 key down 事件,当捕捉到控制移动到另外元素的方向键时:

通过编码把 focus 应用到新元素上,
更改被 focus 中元素上的 tabindex 为“0”
更改之前被 focus 中元素的 tabindex 为“-1”.

方法 2: aria-activedescendant

这个办法包含绑定一个单独的事件句柄到容器窗口组件上,运用 aria-activedescendent属性来追踪一个 "虚拟" 焦点。

键盘事件

使用 onkeydown 来捕获的关键事件,而不是 onkeypress 事件
IE 不会触发非字母数字键的 keypress 事件。使用 onkeydown 替代。

复写focus样式

浏览器默认的focus样式形态各异,用户可以通过在focus时给节点添加focus样式,统一复现,或者直接通过修改css方式,复现outline样式即可。