tabIndex不会使用Tab键使标签可聚焦

hon*_*n2a 41 html5

我正在尝试用图标替换复选框/无线电输入.为此,我需要隐藏原始复选框/收音机.问题是,我还希望表单能够正确支持键盘输入,即让输入通过Tab键保持可聚焦并可选择使用Spacebar.由于我隐藏了输入,因此无法集中注意力,所以相反,我试图使其<label>可聚焦.

这个文档和其他各种来源使我相信我可以使用tabindex属性(对应于HTMLElement.tabIndex属性)来做到这一点.然而,当我尝试分配tabindex给我的标签时,它仍然像以前一样没有重点,无论我多么努力Tab.

为什么不tabindex使标签可以集中?

以下代码段演示了此问题.如果你注重的输入您的鼠标并尝试使用聚焦的标签Tab,这是行不通的(它侧重以下<span>tabindex代替).

document.getElementById('checkbox').addEventListener('change', function (event) {
  document.getElementById('val').innerHTML = event.target.checked;
});
Run Code Online (Sandbox Code Playgroud)
<div>
  <input type="text" value="input">
</div>
<div>
  <label tabindex="0">
    <input type="checkbox" id="checkbox" style="display:none;">
    checkbox: <span id="val">false</span>
  </label>
</div>
<span tabindex="0">span with tabindex</span>
Run Code Online (Sandbox Code Playgroud)

(JavaScript代码只允许看到正确点击标签(联合国)检查复选框.)

Abh*_*lks 60

为什么tabindex没有使标签可以集中?

简答:

  1. 标签是可聚焦的.
  2. TabIndex不会有任何区别.
  3. 欢迎来到浏览器/代理商不一致的世界.

TL;博士;

label (REF)元素是非常可获得焦点.它的DOM接口HTMLLabelElement派生自HTMLElement (Ref),它依次实现GlobalEventHandlers (Ref),从而暴露focus()方法和onfocus事件处理程序.

您无法获得正确的规范/参考文档以获得label焦点行为的原因是因为您可能一直在查看HTML5规范.有趣的是,HTML5 refs没有说明与此相关的任何内容,这增加了混乱.

HTML 4.01参考文献中提到了这一点:http://www.w3.org/TR/html401/interact/forms.html#h-17.9.1

特别是在第17.9.1节末尾和17.10之前:

当LABEL元素获得焦点时,它会将焦点传递给其关联的控件.

此外,在其他地方(我无法掌握参考的那部分)我已经读到它取决于执行代理.(不要相信我的话,我不太确定).

然而,它的意思是,当你focus一个label(或label接收focus),这focus被传递到其相关labeleable控制.这不会导致两个不同的focusES,但一focusinput(你的情况复选框).由于这种行为,tabindex财产无法发挥作用.

W3C还提供了一个关于网站可访问性(WAAG)的测试套件:http://www.w3.org/WAI/UA/TS/html401/cp0102/0102-ONFOCUS-ONBLUR-LABEL.html,其中讨论了实现中onfocusonblurlabel.理想情况下,模拟键盘键盘或辅助技术应该实现这一点.但...

这是浏览器不一致的地方.

这个例子可以证明这一点.在不同的浏览器中查看以下代码段.(我已经针对IE-11,GC-39和FF-34进行了测试.所有这些都表现不同.)

  1. 点击" 焦点标签 " 按钮
  2. 它应该聚焦标签,然后传递焦点并以蓝色突出显示其相关的复选框轮廓.
  3. Chrome-v39有效.IE-v11它没有(不知何故html和正文确实响应:焦点).FF-v34有效.

谈论浏览器不一致,请尝试使用"访问密钥" L.有些浏览器会关注复选框,而有些浏览器会点击它,即将操作传递给它.

这是一个测试它的小提琴:http://jsfiddle.net/abhitalks/ff0xds4z/2/

这是一个片段:

label = $("label").first();
$("#btn").on("click", function() {
    label.focus();
});
Run Code Online (Sandbox Code Playgroud)
* { margin: 8px; }
.highlight { background-color: yellow; }
:focus {
    outline: 2px solid blue;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="txt" type="text" value="input" /><br />
<label for="chk" accesskey="L">Checkbox: </label>
<input id="chk" type="checkbox" /><br />
<input id="btn" type="button" value="Focus Label" />
Run Code Online (Sandbox Code Playgroud)

希望能消除你的疑虑.

.


你的问题:

现在focus唱一首你原来无法聚焦标签的问题(原文如此),因为你想通过在它的位置放置一个图标类型来不同地设置复选框的样式.

为了做到这一点,你可以选择一个选项来完全隐藏它display:none;.相反,将其设为1x1像素并将其推到您的图标下方.这样它仍然可以自然地获得焦点,但却被有效地隐藏起来.

例如,如果您的图标是复选标记十字形,则更改复选框的位置,并使标签上的图标::before::after伪元素.这将导致复选框仍然获得焦点,并使图标响应.这将使图标成为焦点的明显错觉.

演示小提琴:http://jsfiddle.net/abhitalks/v0vxcw77/

片段:

div.chkGroup { position: relative; }
input#chk {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0; margin-top: 4px; outline: none;
    border: 1px solid transparent; background-color: transparent;
}
label::before {
    content: '\2714';
    position: relative;
    width: 18px; height: 18px;
    background-color: #fff;
    margin-right: 8px; padding: 2px;
    display: inline-block; 
    border: 1px solid transparent;
}
input#chk:checked + label::before {
    content: '\2716';
}
input#chk:focus + label::before {
    border: 1px solid #00f;
}
Run Code Online (Sandbox Code Playgroud)
<input id="txt" type="text" value="input" /><br /><br />
<div class="chkGroup">
    <input id="chk" type="checkbox" />
    <label for="chk" accesskey="L">Checkbox</label>
</div>
Run Code Online (Sandbox Code Playgroud)

.