TabIndex не делает ярлык сфокусированным с помощью клавиши Tab
Я пытаюсь заменить флажки/радиовходы с помощью значков. Для этого мне нужно скрыть исходный флажок/радио. Проблема в том, что я также хочу, чтобы форма правильно поддерживала ввод на клавиатуре, т.е. Чтобы вход оставался настраиваемым клавишей Tab
и выбирался с помощью Spacebar
. Поскольку я скрываю ввод, он не может быть сфокусирован, поэтому вместо этого я пытаюсь сделать его <label>
focusable.
Эта документация и различные другие источники привели меня к мысли, что я могу это сделать, используя атрибут tabindex
(соответствующий свойству HTMLElement.tabIndex
). Тем не менее, когда я пытаюсь назначить tabindex
на мой ярлык, он остается таким же несфокусированным, как и раньше, но я стараюсь Tab
на него.
Почему tabindex
не делает ярлык ярким?
Следующий фрагмент демонстрирует проблему. Если вы сконцентрируете ввод с помощью мыши и попытаетесь сфокусировать метку с помощью 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>
Ответы
Ответ 1
Почему tabindex не делает ярлык ярким?
Короткий ответ:
- Ярлык настраивается.
- TabIndex не будет иметь никакого значения.
- Добро пожаловать в мир несоответствий браузера/агента.
TL;DR;
Элемент label
(Ref) очень актуален. Его DOM-интерфейс HTMLLabelElement
, который происходит от HTMLElement
(Ref), который, в свою очередь, реализует GlobalEventHandlers
(Ref) и, следовательно, предоставляет метод focus()
и onfocus
обработчик событий.
Причина, по которой вы не можете получить правильный спецификационный/ссылочный документ для поведения label
focus, заключается в том, что вы, возможно, искали спецификации 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
a label
(или a label
получили a focus
), этот focus
передается соответствующему управляемому элементу управления. Это не приведет к двум различным focus
es, но одному focus
в input
(в вашем случае флажок). Из-за этого поведения свойство tabindex
не может играть роли.
Существует также набор тестов W3C для доступности веб-сайта (WAAG) здесь: http://www.w3.org/WAI/UA/TS/html401/cp0102/0102-ONFOCUS-ONBLUR-LABEL.html, который обсуждает реализацию onfocus
и onblur
для a label
. В идеале клавиатура или вспомогательная технология, которая эмулирует клавиатуру, должна реализовать это. Но...
Здесь несовместимы несовместимости браузера.
Это может быть продемонстрировано в этом примере. Проверьте следующий фрагмент в разных браузерах. (Я тестировал его против IE-11, GC-39 и FF-34. Все они ведут себя по-другому.)
- Нажмите кнопку "Фокусная метка"
- Он должен сфокусировать ярлык, затем передать фокус и выделить его связанный контур флажка в синем.
- Работает Chrome-v39. IE-v11 это не так (как-то html и тело реагируют на: focus). FF-v34 работает.
Говоря о несоответствиях браузера, попробуйте использовать "ключ доступа" L. Некоторые браузеры сфокусируют флажок, тогда как некоторые будут нажимать на него, то есть передать ему действие.
Ниже приведен пример скрипка: 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" />
Ответ 2
Изменить. Ниже было неверное описание спецификации:
Глядя, что полный спецификация, вы увидите, что есть что-то, называемое tabindex focus флаг, который определяет, действительно ли атрибут tabindex
делает поле "Tabbable". Элемент label
отсутствует в этом списке предлагаемых элементы.Дел >
Но опять же, так же, как и элемент span
, поэтому перейдите на рисунок:).
Сказанное: y Вы можете сделать текст ярлыка более привлекательным, обернув все это в другом элементе или используя какой-либо 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>
Ответ 3
Как показали предыдущие плакаты:
Фокус метки всегда обращается непосредственно к элементу ввода.
Довольно раздражает, если у кого-то есть фэнтезийные (но фальшивые) флажки, скрывающие оригинальные, с фактическим фокусом для навигации по клавиатуре нигде не видно.
лучшее решение, о котором я могу думать: javascript.
Сконфигурируйте фактический фокус в пользу поддельного:
input[type=checkbox]:focus {
outline: none;
}
.pseudo-focus {
outline: 2px solid blue;
}
и следить за изменениями в (по многим сценариям явно скрытым) исходным флажком:
$('input[type=checkbox')
.focus( function() {
$(this).closest('label').addClass('pseudo-focus');
})
.blur( function() {
$(this).closest('label').removeClass('pseudo-focus');
});
Полный jsfiddle здесь.
Ответ 4
Для типа входного типа или флажка:
opacity: 0;
height: 0;
width: 0;
min-height: 0;
line-height: 0;
margin: 0;
padding: 0;
border: 0 none;
и Js выше делает трюк сладко.