tabIndex不使用Tab键使标签可以聚焦
我试图用图标replacecheckbox/收音机input。 为此,我需要隐藏原来的checkbox/收音机。 问题是,我也希望窗体正确支持键盘input,即让input保持Tab
键焦点和可选Spacebar
。 因为我隐藏了input,所以不能集中注意力,所以我试图使它的<label>
可调焦。
这个文档和各种其他来源使我相信我可以使用tabindex
属性(对应于HTMLElement.tabIndex
属性)来做到这一点。 但是,当我尝试将tabindex
分配给我的标签时,它仍然像以往一样不专心,无论我尝试Tab
还是如此。
为什么不tabindex
使标签可重点?
以下片段演示了这个问题。 如果你用鼠标把input集中在一起,并尝试使用Tab
对标签进行聚焦,它将不起作用(它会将下面的<span>
用tabindex
来代替)。
document.getElementById('checkbox').addEventListener('change', function (event) { document.getElementById('val').innerHTML = event.target.checked; });
<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>
(JavaScript代码只是允许看到正确点击标签(联合国)检查checkbox。)
为什么不tabindex使标签可重点?
简答 :
- 标签是可以聚焦的。
- TabIndex不会有任何区别。
- 欢迎来到浏览器/代理不一致的世界。
TL;博士;
label
(Ref)元素非常适合。 它的DOM接口是HTMLLabelElement
,它来自HTMLElement
(Ref) ,而HTMLElement
(Ref)又实现了GlobalEventHandlers
(Ref) ,从而暴露了focus()
方法和onfocus
事件处理程序。
你无法得到适当的规范/参考文件label
的焦点行为的原因,因为你可能一直在看HTML5规格。 有趣的是,HTML5的参考并没有说明任何有关的,这增加了混乱。
这在HTML 4.01 Ref中提到: http : //www.w3.org/TR/html401/interact/forms.html#h-17.9.1
特别是在第17.9.1节的末尾以及17.10之前:
当LABEL元素获得焦点时,它将焦点传递给其关联的控件。
另外,在其他地方( 我无法掌握裁判的这一部分 )我已经读过,这取决于执行代理。 ( 不要拿我的话,我不太确定 )。
然而,这意味着当你focus
一个label
(或者一个label
获得focus
)时,这个focus
被传递给它相关的标签控件。 这不会导致两个不同的focus
,但一个focus
于input
(在你的情况下一个checkbox)。 由于这种行为, tabindex
属性不能发挥作用。
W3C还有一个testing套件,用于网站访问(WAAG): http : //www.w3.org/WAI/UA/TS/html401/cp0102/0102-ONFOCUS-ONBLUR-LABEL.html ,其中讨论了实现onfocus
和onblur
的label
。 理想情况下,模拟键盘的键盘或辅助技术应该实现这一点。 但…
这是浏览器不一致性发挥作用的地方。
这可以通过这个例子来certificate。 在不同的浏览器中检查以下片段。 (我已经对IE-11,GC-39和FF-34进行了testing,它们的performance都不一样)。
- 点击button“ 焦点标签 ”
- 它应该关注标签,然后传递焦点并以蓝色突出显示其关联的checkbox大纲。
- Chrome-v39的作品。 IE-V11它不(以某种方式HTML和身体做回应:重点)。 它的工作原理FF-V34。
在谈到浏览器不一致时,请尝试使用“访问键” L。 有些浏览器会关注checkbox,而有些则会点击它,即将操作传递给它。
这里是一个小提琴来testing它: http : //jsfiddle.net/abhitalks/ff0xds4z/2/
这是一个片段 :
label = $("label").first(); $("#btn").on("click", function() { label.focus(); });
* { margin: 8px; } .highlight { background-color: yellow; } :focus { outline: 2px solid blue; }
<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" />
编辑 :以下是规范的误读:
看看完整的规范 ,你会看到有一些叫做tabindex焦点标志 ,它定义了tabindex
属性是否实际上使字段“tabbable”。 build议元素列表中缺lesslabel
元素。
但是再次,span
元素也是如此,所以去图:)。
这就是说, 您可以通过将整个事物包装在另一个元素中,或者使用一些JavaScript来强制解决问题,从而使标签文本成为可聚焦的。 不幸的是,包装(在这里是一个锚点)可以在CSS和JS中进行相当多的额外工作,以像普通label
元素一样工作。
document.getElementById('checkbox').addEventListener('change', function(event) { document.getElementById('val').innerHTML = event.target.checked; }); document.getElementsByClassName('label')[0].addEventListener('click', function(event) { event.target.getElementsByTagName('label')[0].click(); event.preventDefault(); }); document.getElementsByClassName('label')[0].addEventListener('keypress', function(event) { if ((event.key || event.which || event.keyCode) === 32) { event.target.getElementsByTagName('label')[0].click(); event.preventDefault(); } });
.label, .label:visited, .label:hover, .label:active { text-decoration: none; color: black; }
<div> <input type="text" value="input"> </div> <div> <a class="label" href="#"> <label tabindex="0"> <input type="checkbox" id="checkbox" style="display:none;">checkbox: <span id="val">false</span> </label> </a> </div> <span tabindex="0">span with tabindex</span>
正如之前的海报所说: 标签焦点总是直接进入input元素。
如果有人喜欢(但假的)checkbox,隐藏原来的,真实的焦点,键盘导航无处可见,这是一个非常烦恼。
我能想到的最佳解决scheme:javascript。
风格 – 实际的重点,有利于一个假的:
input[type=checkbox]:focus { outline: none; } .pseudo-focus { outline: 2px solid blue; }
并观察(在许多情况下可见隐藏)原来的checkbox的变化:
$('input[type=checkbox') .focus( function() { $(this).closest('label').addClass('pseudo-focus'); }) .blur( function() { $(this).closest('label').removeClass('pseudo-focus'); });
完整的jsfiddle在这里 。
对于inputtypes收音机或checkbox:
opacity: 0; height: 0; width: 0; min-height: 0; line-height: 0; margin: 0; padding: 0; border: 0 none;
而上面的Js甜蜜地诀窍。