Модуль ally.get.focusTarget библиотеки
ally.js предназначен для определения реального
элемента, который должен получить фокус. В интерфейсах, построенных на
сложных DOM-структурах, не всегда очевидно, какой узел станет
фактической целью фокуса. Некоторые элементы перенаправляют фокус внутрь
себя, другие не являются фокусируемыми напрямую, а некоторые требуют
специальной обработки из-за особенностей браузеров и стандартов
доступности.
ally.get.focusTarget выполняет анализ элемента и
возвращает корректный DOM-узел, который действительно может принять
фокус. Такой подход особенно важен при реализации:
focus() в различных браузерах.Функция позволяет устранить различия между теоретически фокусируемым элементом и фактической точкой получения фокуса.
Многие HTML-элементы ведут себя как контейнеры фокуса. При попытке сфокусировать такой контейнер браузер фактически переносит фокус на другой элемент внутри него.
Примеры:
label переносит фокус на связанный элемент формы;fieldset может передавать фокус первому интерактивному
элементу;summary управляет фокусом внутри
details;contenteditable имеют собственную логику
фокусировки.ally.get.focusTarget анализирует:
после чего возвращает корректный узел.
В проектах с модульной архитектурой функция подключается отдельно:
import getFocusTarget from 'ally.js/get/focus-target';
После импорта функция может применяться к любому DOM-элементу.
const element = document.querySelector('.control');
const target = getFocusTarget(element);
target.focus();
В этом примере:
focus().Если элемент сам способен принимать фокус, функция возвращает его же.
Для стандартных элементов управления функция возвращает исходный элемент.
const button = document.querySelector('button');
const target = getFocusTarget(button);
console.log(target === button);
К таким элементам относятся:
buttoninputtextareaselecttabindexВ этих случаях дополнительной логики перенаправления не требуется.
labellabel часто используется как контейнер для элемента
формы. При фокусировке метки браузер переводит фокус на связанный
контрол.
<label for="email">Email</label>
<input id="email">
Использование функции:
const label = document.querySelector('label');
const target = getFocusTarget(label);
Функция вернёт элемент input, а не
label.
Это особенно полезно при программной фокусировке:
getFocusTarget(label).focus();
Без этой логики попытка фокусировки могла бы работать непредсказуемо.
Если интерактивный элемент находится внутри label,
библиотека также корректно определяет цель.
<label>
Username
<input type="text">
</label>
В этом случае:
const label = document.querySelector('label');
const target = getFocusTarget(label);
Результатом снова станет input.
fieldsetКонтейнер fieldset может содержать множество элементов
управления. Сам по себе он редко является конечной точкой фокуса.
ally.get.focusTarget ищет внутри него наиболее
подходящий элемент:
Пример:
<fieldset>
<legend>Account</legend>
<input type="text">
</fieldset>
const fieldset = document.querySelector('fieldset');
const target = getFocusTarget(fieldset);
Функция возвращает input.
tabindexЭлементы с tabindex могут становиться фокусируемыми даже
если по умолчанию такими не являются.
<div tabindex="0"></div>
В таком случае:
const element = document.querySelector('div');
const target = getFocusTarget(element);
Функция возвращает сам div, поскольку он уже пригоден
для фокусировки.
Если элемент не может получать фокус и не имеет вложенных целей
фокусировки, функция возвращает null.
const element = document.querySelector('span');
const target = getFocusTarget(element);
console.log(target);
Такое поведение позволяет безопасно проверять результат:
const target = getFocusTarget(element);
if (target) {
target.focus();
}
Элементы с contenteditable являются отдельной категорией
фокусируемых узлов. Они обладают собственной логикой ввода и
редактирования текста.
<div contenteditable="true"></div>
При использовании функции:
const editable = document.querySelector('[contenteditable]');
const target = getFocusTarget(editable);
возвращается тот же элемент, поскольку он сам является точкой ввода.
Функция принимает два аргумента:
getFocusTarget(element, options);
element — DOM-узел, для которого требуется определить
цель фокуса.options — объект дополнительных параметров.Большинство сценариев обходится без дополнительных опций, однако библиотека позволяет уточнять поведение при необходимости.
ally.get.focusTarget часто применяется совместно с
другими модулями библиотеки:
ally.query.focusableally.query.tabbableally.element.focusТипичный сценарий управления фокусом:
import getFocusTarget from 'ally.js/get/focus-target';
import focusElement from 'ally.js/element/focus';
const element = document.querySelector('.dialog');
const target = getFocusTarget(element);
focusElement(target);
Такой подход обеспечивает:
При создании интерактивных интерфейсов часто возникают контейнерные элементы, внутри которых находится настоящий контрол.
Пример пользовательского компонента:
<div class="custom-input">
<input type="text">
</div>
Фокусировка контейнера:
const container = document.querySelector('.custom-input');
getFocusTarget(container).focus();
Функция автоматически найдёт подходящий элемент внутри контейнера.
Модальные окна требуют строгого управления фокусом. При открытии окна необходимо переместить фокус внутрь интерфейса.
Пример:
const dialog = document.querySelector('.dialog');
const target = getFocusTarget(dialog);
if (target) {
target.focus();
}
Такой механизм гарантирует, что фокус окажется на реальном интерактивном элементе.
Навигация с клавиатуры требует точного определения фокусируемых элементов. Ошибка в выборе цели может привести к:
ally.get.focusTarget предотвращает подобные проблемы,
определяя корректную точку фокусировки.
Разные браузеры по-разному обрабатывают попытку фокусировки некоторых элементов. Например:
Библиотека ally.js учитывает эти различия и возвращает согласованный результат.
Основные ситуации использования:
1. Программная фокусировка
getFocusTarget(element).focus();
2. Управление фокусом в компонентах
const control = getFocusTarget(component);
3. Проверка фокусируемости
const target = getFocusTarget(element);
if (!target) {
console.log('Фокус невозможен');
}
Использование ally.get.focusTarget решает ряд
распространённых проблем:
label и другими контейнерными
элементами;В сложных интерфейсах, содержащих кастомные элементы управления, функция становится важным инструментом для надёжной и предсказуемой фокусировки DOM-элементов.