Chrome DevTools запускает полное дерево доступности, благодаря чему разработчикам будет проще получить обзор всего дерева. В этом посте вы узнаете, как создается это дерево и как использовать его в своей работе.
Что такое дерево доступности?
Вспомогательные технологии, такие как программы чтения с экрана, используют API специальных возможностей Chromium для взаимодействия с веб-контентом. Базовой моделью этого API является дерево доступности: дерево объектов доступности, к которым вспомогательные технологии могут запрашивать атрибуты и свойства и выполнять действия над ними . Веб-разработчики формируют дерево доступности и манипулируют им в первую очередь с помощью свойств DOM, таких как атрибуты ARIA для HTML .
В Chrome DevTools мы предоставляем панель специальных возможностей, которая помогает разработчикам понять, как их контент подвергается воздействию вспомогательных технологий. Конкретно, когда узел выбран в средстве просмотра дерева DOM, свойства соответствующего узла доступности отображаются на панели вместе с представлением предков узла и его непосредственных дочерних элементов.
Как создается дерево?
Прежде чем мы перейдем к тому, как выглядит это новое полное древовидное представление в DevTools, давайте кратко рассмотрим, что такое дерево доступности в более осязаемых терминах. Дерево доступности является производным от дерева DOM. Его структура примерно такая же, но упрощена за счет удаления узлов без семантического содержания, таких как элемент <div>
, используемый исключительно для стилизации. Каждый узел в дереве имеет роль, например Button
или Heading
, и часто имя, которое может быть либо из атрибутов ARIA, либо получено из содержимого узла. Если мы посмотрим на HTML-документ:
<html>
<head>
<title>How old are you?</title>
</head>
<body>
<label for="age">Age</label>
<input id="age" type="number" name="age" value="42">
<div>
<button>Back</button>
<button>Next</button>
</div>
</body>
</html>
Средство рендеринга в Chromium, называемое Blink, создает внутреннее дерево доступности примерно следующим образом.
role='rootWebArea' focusable name='How old are you?'
role='genericContainer' ignored
role='genericContainer' ignored
role='labelText'
role='staticText' name='Age'
role='spinButton' editable focusable name='Age' value='42'
role='genericContainer' editable
role='staticText' editable name='42'
role='genericContainer'
role='button' focusable name='Back'
role='staticText' name='Back'
role='button' focusable name='Next'
role='staticText' name='Next'
Обратите внимание, что это представление содержит несколько лишних узлов с ролью genericContainer
, что, по-видимому, противоречит приведенному выше утверждению о том, что дерево доступности является упрощенной производной от дерева DOM. Тем не менее, большинство этих узлов встречаются только во внутреннем дереве и не будут подвергаться воздействию вспомогательных технологий. Поскольку DevTools собирает информацию о доступности непосредственно из процесса рендеринга, DevTools обрабатывает именно древовидное представление.
Полное дерево доступности в DevTools
Новое дерево полной доступности синхронизировано с деревом DOM, поэтому разработчики могут переключаться между двумя деревьями. Мы надеемся, что новое дерево окажется более доступным для изучения, полезным и простым в использовании.
Теперь, когда вы знаете, как работает дерево доступности, вы можете использовать DevTools, чтобы увидеть, как выглядит новое древовидное представление. Следующий HTML-документ с заголовком, заголовком и двумя кнопками используется для отображения дерева.
<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
<button>Back</button>
<button>Next</button>
</div>
Предыдущее представление дерева позволяло вам исследовать только один узел и его предков.
Теперь, когда вы переключаете новое дерево, оно заменяет представление дерева DOM и позволяет вам увидеть полное дерево доступности для страницы:
Ленивое построение дерева
Чтобы сделать дерево производительным даже для больших сайтов, дерево лениво строится во внешнем интерфейсе по мере его исследования. После расширения узла в дереве дочерние узлы извлекаются через протокол Chrome DevTools (CDP), и дерево перестраивается.
Жить
Новое древовидное представление является активным и динамически обновляется, если дерево доступности изменяется в средстве визуализации. Он подключается к той же механике, которая уведомляет вспомогательные технологии об изменениях в дереве, и использует ее для отправки событий в интерфейс DevTools с обновленными узлами. На практике серверная часть CDP прослушивает обновления дерева, отслеживает, какие узлы были запрошены ранее, и отправляет события во внешний интерфейс DevTools, если какой-либо из этих узлов изменяется.
Сказка о многих деревьях
Из описания того , что такое дерево доступности, вы узнали, как Blink создает дерево доступности для DOM, который он отображает, а DevTools извлекает это дерево через CDP. Хотя это и правда, мы не включили в это описание некоторые сложности. На самом деле существует довольно много разных способов использовать дерево доступности в Chromium. При разработке нового древовидного представления для DevTools мы сделали выбор в отношении того, какую часть внутренних возможностей специальных возможностей Chromium мы хотели бы раскрыть.
Платформы
Каждая платформа имеет свой API доступности, и хотя форма дерева одинакова на всех платформах, API для взаимодействия с деревом различен, а имена атрибутов могут различаться. DevTools показывает внутреннее дерево Chromium, в котором роли и атрибуты обычно соответствуют тем, которые определены в спецификации ARIA .
Несколько фреймов и изоляция сайта
Поскольку Chromium не только помещает содержимое каждой вкладки в разные процессы рендеринга, но также изолирует межсайтовые документы в разных процессах рендеринга , нам приходится подключаться к каждому внепроцессному дочернему документу отдельно через CDP и получать его дерево доступности. Затем мы сшиваем эти поддеревья вместе во внешнем интерфейсе, чтобы создать иллюзию одного связного дерева, хотя в Chromium они находятся в разных процессах рендеринга.
Игнорируемые и неинтересные узлы
По умолчанию мы скрываем некоторые узлы: игнорируемые узлы и узлы с ролью «generic» без имени. Эти узлы не несут никакого семантического значения и, в случае игнорируемых узлов, не подвергаются воздействию вспомогательных технологий. Мы скрываем эти узлы, чтобы не загромождать древовидное представление. Если бы мы этого не сделали, дерево доступности для большинства веб-страниц выглядело бы примерно так:
Предостережение здесь в том, что по сути это означает, что нам нужно построить еще одно дерево, отличное от того, которое доступно на бэкэнде. Скажем, например, что у нас есть узлы A, B, C и X, где у A есть дочерние элементы X и B, а у X есть дочерние узлы C. Если узел X игнорируется, мы удаляем X из дерева и вместо этого создаем дерево, в котором С — ребенок А.
Во внешнем интерфейсе мы строим полное дерево, включая игнорируемые узлы, и обрезаем их только непосредственно перед отрисовкой узлов. Мы делаем это по двум причинам:
- Это значительно упрощает обработку обновлений узлов из бэкэнда , поскольку на обеих конечных точках у нас одинаковая древовидная структура. Например, если в этом примере узел B удален, мы получим обновление для узла X (поскольку его дочерние элементы изменились), но если бы мы сократили этот узел, нам было бы сложно выяснить, что обновлять.
- Это гарантирует, что все узлы DOM имеют соответствующий узел доступности. Когда дерево переключается, мы выбираем узел, соответствующий узлу, выбранному в данный момент в дереве DOM. Итак, в предыдущем примере, если пользователь переключает дерево, когда выбран узел DOM, соответствующий X, мы вводим X между узлами A и B и выбираем X в дереве. Это позволяет пользователю проверить узел доступности для всех узлов DOM и помочь определить, почему узел игнорируется.
Идеи будущего
Запуск нового дерева доступности — это только начало. У нас есть несколько идей для будущих проектов, которые мы могли бы реализовать на основе нового представления, но мы также хотим услышать ваши отзывы !
Альтернативные фильтры
Как объяснялось выше, в настоящее время мы отфильтровываем узлы, которые считаются неинтересными. Мы могли бы предоставить способ отключить это поведение и показать все узлы или предоставить альтернативные фильтры, такие как «Показать узлы ориентиров» или «Показать заголовки» .
Выделите все проблемы
Мы могли бы включить в дерево анализ «лучших практик доступности» и выявить проблемы доступности непосредственно на узлах-нарушителях.
Действия по обеспечению доступности поверхности в DevTools
Дерево, которое мы показываем, является чисто односторонним: оно позволяет нам получить представление о том, какая информация будет передаваться вспомогательным технологиям при просмотре конкретной веб-страницы. Действия по обеспечению доступности представляют собой общение в другом направлении: они позволяют вспомогательным технологиям воздействовать на представленный пользовательский интерфейс. Мы могли бы отображать такие действия в DevTools, чтобы разрешить такие действия, как «щелчок», прокрутка или изменение значений на странице, с помощью API, доступного для вспомогательных технологий.