Библиотека Aria-query предназначена для работы с ARIA-ролями и атрибутами в контексте веб-разработки, предоставляя структурированные данные о доступности интерфейсов. Одной из ключевых возможностей является поиск элементов, соответствующих определённой роли, что критически важно для тестирования доступности и построения динамических пользовательских интерфейсов.
Aria-query оперирует двумя базовыми структурами данных:
Каждая роль включает в себя следующие свойства:
name — идентификатор роли.superClass — роли, от которых наследуется текущая.props — список ARIA-атрибутов, применимых к роли.abstract — флаг, показывающий, является ли роль
абстрактной.Для работы с Aria-query необходимо импортировать соответствующие модули:
import { roles, elementRoles } from 'aria-query';
После импорта можно получить доступ к структурам данных, где
roles содержит карты всех ролей, а
elementRoles — информацию о том, какие HTML-теги могут быть
использованы с какой ролью.
Для поиска всех элементов, соответствующих определённой роли,
используется подход обхода elementRoles. Пример
функции:
function findElementsByRole(roleName) {
const matchingElements = [];
elementRoles.forEach((rolesSet, elementName) => {
if (rolesSet.has(roleName)) {
matchingElements.push(elementName);
}
});
return matchingElements;
}
Здесь elementRoles — это Map, где ключи —
HTML-теги, а значения — Set ролей, допустимых для элемента.
Функция перебирает все элементы и проверяет наличие нужной роли.
Пример использования:
const buttonElements = findElementsByRole('button');
console.log(buttonElements); // ['button', 'input', 'a']
Иногда необходимо проверить, может ли конкретный элемент HTML иметь
определённую роль. Для этого используется метод has из
Set:
function elementHasRole(elementName, roleName) {
const rolesSet = elementRoles.get(elementName);
return rolesSet ? rolesSet.has(roleName) : false;
}
console.log(elementHasRole('input', 'textbox')); // true
console.log(elementHasRole('div', 'button')); // false
Абстрактные роли не могут напрямую применяться к элементам, но их
наследники могут. Чтобы учесть это, необходимо фильтровать роли по
abstract и использовать superClass для поиска
всех реальных ролей:
function findConcreteRoles(roleName) {
const role = roles.get(roleName);
if (!role) return [];
if (!role.abstract) return [roleName];
const concreteRoles = [];
roles.forEach((r, name) => {
if (r.superClass && r.superClass.has(roleName) && !r.abstract) {
concreteRoles.push(name);
}
});
return concreteRoles;
}
Этот подход позволяет найти все доступные HTML-элементы, которые косвенно соответствуют абстрактной роли.
Иногда требуется объединить поиск элементов и проверку конкретной роли, включая наследование:
function findElementsForRoleIncludingAbstract(roleName) {
const concreteRoles = findConcreteRoles(roleName);
const elements = new Set();
elementRoles.forEach((rolesSet, elementName) => {
concreteRoles.forEach(cr => {
if (rolesSet.has(cr)) {
elements.add(elementName);
}
});
});
return Array.from(elements);
}
console.log(findElementsForRoleIncludingAbstract('range'));
// ['input', 'meter', 'progress', 'select']
Set вместо массива для предотвращения
дублирования элементов.Работа с Aria-query обеспечивает строгий контроль соответствия интерфейса стандартам ARIA и значительно упрощает построение доступных веб-приложений, особенно при динамическом создании элементов.