Как повторить tabindex от 1 после того, как он перешел к последнему элементу с tabindex?

Итак, например, здесь script:

<!-- Random content above this comment -->
<input type="text" tabindex="1" />
<input type="text" tabindex="2" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<!-- Nothing underneath this comment -->

Итак, когда пользователь нажимает вкладку и проходит через шесть текстовых полей, достигает последней, а затем нажимает вкладку, она переходит к содержимому выше первого комментария, правильно? Ну, как я могу начать с tabindex="1" снова?

Ответы

Ответ 1

К сожалению, вы не можете сделать это без javascript. Вы можете прослушивать TAB (и не заставлять клавишу SHIFT + TAB) нажать последний элемент и вручную установить фокус на свой первый элемент внутри обработчика. Однако привязка этой логики к событиям клавиатуры (т.е. Конкретному методу ввода) не является универсальной и может не работать при использовании:

  • Мобильный браузер
  • Некоторые другие развлекательные устройства (интеллектуальное телевидение, игровая консоль и т.д.), они обычно используют D-Pad для перехода между фокусируемыми элементами.
  • Служба доступности

Я предлагаю более универсальный подход, который не зависит от изменения фокуса.

Идея состоит в том, что вы окружаете элементы формы (там, где вы хотите создать цикл "tabindex" ) со специальными элементами "фокуса", которые тоже фокусируются (у них есть назначенный tabindex). Вот ваш измененный HTML:

<p>Some sample <a href="#" tabindex="0">content</a> here...</p>
<p>Like, another <input type="text" value="input" /> element or a <button>button</button>...</p>

<!-- Random content above this comment -->
<!-- Special "focus guard" elements around your
if you manually set tabindex for your form elements, you should set tabindex for the focus guards as well -->
<div class="focusguard" id="focusguard-1" tabindex="1"></div>
<input id="firstInput" type="text" tabindex="2" class="autofocus" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<input id="lastInput" type="text" tabindex="7" />
<!-- focus guard in the end of the form -->
<div class="focusguard" id="focusguard-2" tabindex="8"></div>
<!-- Nothing underneath this comment -->

Теперь вы просто слушаете события focus для этих элементов защиты и вручную меняете фокус на соответствующее поле (jQuery используется для простоты):

$('#focusguard-2').on('focus', function() {
  // "last" focus guard got focus: set focus to the first field
  $('#firstInput').focus();
});

$('#focusguard-1').on('focus', function() {
  // "first" focus guard got focus: set focus to the last field
  $('#lastInput').focus();
});

Как вы видите, я также убедился, что мы привязываемся к последнему входу, когда фокус перемещается назад от первого входа (например, SHIFT + TAB на первом входе). Пример в реальном времени

Обратите внимание, что для защиты от фокуса также назначается значение tabindex, чтобы убедиться, что они сфокусированы непосредственно перед/после полей ввода. Если вы не вручную устанавливаете tabindex на свои входы, то оба защитных устройства могут иметь только tabindex="0".

Конечно, вы можете заставить все работать в динамической среде, когда ваша форма генерируется динамически. Просто сравните свои настраиваемые элементы (менее тривиальная задача) и окружите их теми же защитными элементами.

Надеюсь, что это поможет, сообщите мне, есть ли у вас какие-либо проблемы.

UPDATE

Как отмечалось в nbro, вышеупомянутая реализация имеет нежелательный эффект выбора последнего элемента, если он обращается к TAB после загрузки страницы (поскольку это будет фокусировать первый фокусируемый элемент, который равен #focusguard-1, и это вызовет фокусировку последний вход. Чтобы смягчить это, вы можете указать, какой элемент вы хотите сфокусировать, и сфокусировать его на другом маленьком фрагменте JavaScript:

$(function() { // can replace the onload function with any other even like showing of a dialog

  $('.autofocus').focus();
})

С этим просто установите класс autofocus на любой элемент, который вы хотите, и он будет сфокусирован на загрузке страницы (или любом другом событии, которое вы слушаете).

Ответ 2

Здесь мое решение, где вам не нужны какие-либо другие элементы. Как вы видите, элементы будут циклироваться внутри элементов <form>.

$('form').each(function(){
    var list  = $(this).find('*[tabindex]').sort(function(a,b){ return a.tabIndex < b.tabIndex ? -1 : 1; }),
        first = list.first();
    list.last().on('keydown', function(e){
        if( e.keyCode === 9 ) {
            first.focus();
            return false;
        }
    });
});

Ответ 3

Вот мое решение, учитывая, что первый вход имеет атрибут "автофокус":

Добавьте это после элемента формы (с HTML5 это может быть любой тег):

<div tabindex="6" onFocus="document.querySelector('[autofocus]').focus()"></div>

Ответ 4

Я предлагаю вам увеличить ваш tabindex, т.е. > 100  а также предоставить tabIndex вашему контейнеру "content" div обратите внимание, что ваш контейнер содержимого должен иметь tabindex меньше, чем поля ввода для ex.99.

когда вы нажимаете вкладку в последнем поле ввода вручную, установите фокус на свой контент div с помощью javascript (вы можете использовать обработчики нажатия клавиш для клавиши табуляции)

document.getElementById("content").focus();

вы должны giv tabindex в свой "контент", чтобы установить фокус на него.

теперь, если вы нажмете вкладку, фокус автоматически переключится на первое поле ввода.

надеюсь, что это поможет.

Спасибо

Ответ 5

Да, после внесения вкладок через входы он перескакивает на подходящие элементы, у которых нет указанного порядка табуляции. Но также, после внесения вкладок во все элементы "tabbable", фокус будет "наружу" содержимое вашей страницы, в элементы пользовательского интерфейса браузера (вкладки, меню, закладки и т.д.).

Я думаю, что самый простой способ - обработать событие keyup на последнем входе и перехватить TAB использование (и SHIFT + TAB, если на то пошло)