Ответ 1
В интересах полноты, я беру ссылку на диалог jQuery UI, который @Domenic предоставил и заполнил детали.
Для реализации этого в модуле jQuery требуется две вещи:
-
Прослушивание
Tab
илиShift+Tab
(наkeydown
) для модального элемента, который должен удерживать фокус. Это единственный способ перемещения фокуса с клавиатуры. (Если вы хотите предотвратить взаимодействие с мышью с остальной частью документа, это отдельная проблема, решаемая путем покрытия ее элементом, чтобы предотвратить прохождение каких-либо событий мыши.) -
Поиск всех элементов табуляции внутри модального элемента. Это подмножество всех фокусируемых элементов, исключая те, которые имеют
tabindex="-1"
.
Tab
идет вперед. Shift+Tab
идет назад. При каждом нажатии Tab
, когда последний элемент tabbable в модальном элементе сфокусирован, первый должен получать фокус. Точно так же в любое время Shift+Tab
нажимается, когда первый сменный элемент сфокусирован, последний должен получать фокус. Это будет держать фокус внутри модального элемента.
Жесткая часть - это знание того, какие элементы табулируются. Так как элементы tabbable являются элементами фокусирующегося, которые не имеют tabindex="-1"
, тогда нам нужно знать, какие элементы являются ориентируемыми. Поскольку нет свойства, чтобы определить, является ли элемент ориентируемым, jQuery использует жесткое кодирование следующих случаев:
-
input
,select
,textarea
,button
иobject
элементы, которые не отключены. -
a
иarea
, которые имеютhref
или имеют числовое значение дляtabindex
. - любой элемент, который имеет числовое значение для
tabindex
.
Этого недостаточно, чтобы проверить эти три случая. jQuery продолжает следить за тем, чтобы элемент был виден. Это означает, что оба значения должны быть истинными:
- Ни один из его предков
display: none
. - Вычисленное значение
visibility
равноvisible
. Это означает, что ближайший предок, имеющий наборvisibility
, должен иметь значениеvisible
. Если никакой предок не установленvisibility
, тогда вычисленное значениеvisible
.
Следует отметить, что jQuery :visible
селектор не подходит для этой реализации, потому что он говорит: "Элементы с visibility: hidden
... являются считаются видимыми", но они не могут быть сфокусированы.