Подтвердить что ты не робот

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>
4b9b3361

Ответ 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 выше делает трюк сладко.