JavaScript¶
JavaScript играет важную роль практически во всем, что мы создаем — от небольших динамических компонентов до полноценных продуктов, работающих на JavaScript-фреймворках, таких как React или Angular.
Это использование (или чрезмерное использование) JavaScript породило множество тревожных тенденций, таких как длительное время загрузки из-за большого количества кода, использование несемантических HTML-элементов и внедрение HTML и CSS через JavaScript. И вы можете быть не уверены в том, как доступность вписывается в каждую из этих частей.
JavaScript может сильно повлиять на доступность вашего сайта. В этом модуле мы поделимся некоторыми общими паттернами доступности, которые улучшаются с помощью JavaScript, а также решениями проблем доступности, возникающих при использовании JavaScript-фреймворков.
События триггеров¶
События JavaScript позволяют пользователям взаимодействовать с веб-контентом и выполнять определенные действия. Многие люди, такие как пользователи программ чтения с экрана, люди с нарушениями мелкой моторики, люди без мыши или трекпада и другие, полагаются на поддержку клавиатуры для взаимодействия с веб-интерфейсом. Крайне важно добавить поддержку клавиатуры к вашим JavaScript-действиям, поскольку это затрагивает всех этих пользователей.
Давайте рассмотрим событие клика. Если событие onClick()
используется на семантическом HTML-элементе, таком как <button>
или <a>
, оно естественным образом включает в себя функциональность как мыши, так и клавиатуры. Однако функциональность клавиатуры не применяется автоматически, когда событие onClick()
добавляется к несемантическому элементу, такому как обычный <div>
.
Плохо | |
---|---|
1 |
|
Лучше | |
---|---|
1 |
|
Посмотрите на это сравнение на CodePen.
Если несемантический элемент используется для события триггера, должно быть добавлено событие keydown/keyup для обнаружения нажатия клавиш Enter или Space. Добавление событий триггеров к несемантическим элементам часто забывается. К сожалению, когда это забывается, результатом является компонент, доступный только через мышь. Пользователи, использующие только клавиатуру, остаются без доступа к связанным действиям.
Заголовки страниц¶
Как мы узнали в модуле документа, заголовок страницы важен для пользователей программ чтения с экрана. Он сообщает пользователям, на какой странице они находятся и перешли ли они на новую страницу.
Если вы используете JavaScript-фреймворк, вам необходимо учитывать, как вы обрабатываете заголовки страниц. Это особенно важно для одностраничных приложений (SPA), которые загружаются из единственного файла index.html
, поскольку переходы или маршруты (изменения страниц) не будут включать перезагрузку страницы. Каждый раз, когда пользователь загружает новую страницу в SPA, заголовок по умолчанию не изменится.
Для SPA значение document.title может быть добавлено вручную или с помощью вспомогательного пакета (в зависимости от JavaScript-фреймворка). Объявление обновленных заголовков страниц пользователю программы чтения с экрана может потребовать дополнительной работы, но хорошие новости в том, что у вас есть варианты, такие как динамический контент.
Динамический контент¶
Одной из самых мощных функций JavaScript является возможность добавлять HTML и CSS к любому элементу на странице. Разработчики могут создавать динамические приложения на основе действий или поведения пользователей.
Допустим, вам нужно отправить сообщение пользователям, когда они входят в ваш веб-сайт или приложение. Вы хотите, чтобы сообщение выделялось на белом фоне и передавало сообщение: "Вы теперь вошли в систему."
Вы можете использовать элемент innerHTML
для установки содержимого:
1 2 |
|
Вы можете применить CSS аналогичным образом, с помощью setAttribute
:
1 2 3 |
|
С большой силой приходит большая ответственность. К сожалению, внедрение HTML и CSS через JavaScript исторически неправильно использовалось для создания недоступного контента. Вот некоторые распространенные злоупотребления:
Возможное злоупотребление | Правильное использование |
---|---|
Рендеринг больших блоков несемантического HTML | Рендеринг меньших частей семантического HTML |
Недостаточное время для распознавания динамического контента вспомогательными технологиями | Использование задержки времени setTimeout() , чтобы позволить пользователям услышать полное сообщение |
Динамическое применение атрибутов стиля для onFocus() | Используйте :focus для связанных элементов в вашей CSS таблице стилей |
Применение встроенных стилей может привести к тому, что пользовательские таблицы стилей не будут читаться правильно | Храните ваши стили в CSS-файлах для поддержания согласованности темы |
Создание очень больших JavaScript-файлов, которые замедляют общую производительность сайта | Используйте меньше JavaScript. Вы можете выполнять аналогичные функции в CSS (такие как анимации или липкая навигация), которые парсятся быстрее и более производительны |
Для CSS переключайте CSS-классы вместо добавления встроенных стилей, поскольку это обеспечивает возможность повторного использования и простоту. Используйте скрытый контент на странице и переключайте классы для скрытия и показа контента для динамического HTML. Если вам нужно использовать JavaScript для динамического добавления контента на вашу страницу, убедитесь, что он простой и лаконичный, и, конечно же, доступный.
Управление фокусом¶
В модуле фокуса клавиатуры мы рассматривали порядок фокуса и стили индикаторов. Управление фокусом — это знание того, когда и где захватывать фокус и когда его не следует захватывать.
Управление фокусом критически важно для пользователей, использующих только клавиатуру.
Управление фокусом на уровне компонента¶
Вы можете создать ловушки клавиатуры, когда фокус компонента не управляется должным образом. Ловушка клавиатуры возникает, когда пользователь, использующий только клавиатуру, застревает в компоненте, или фокус не поддерживается, когда должен.
Одним из наиболее распространенных паттернов, где пользователи сталкиваются с проблемами управления фокусом, является модальный компонент. Когда пользователь, использующий только клавиатуру, сталкивается с модальным окном, пользователь должен иметь возможность переключаться между действующими элементами модального окна, но ему никогда не должно быть разрешено выйти за пределы модального окна без явного его закрытия. JavaScript необходим для правильного захвата этого фокуса.
Плохо
Хорошо
Управление фокусом на уровне страницы¶
Фокус также должен поддерживаться, когда пользователь переходит со страницы на страницу. Это особенно верно для SPA, где нет обновления браузера, и весь контент изменяется динамически. Каждый раз, когда пользователь нажимает на ссылку для перехода на другую страницу в вашем приложении, фокус либо остается в том же месте, либо потенциально размещается где-то еще.
При переходе между страницами (или маршрутизации) команда разработки должна решить, куда переходит фокус при загрузке страницы.
Существует несколько техник для достижения этого:
- Поместить фокус на основной контейнер с объявлением
aria-live
. - Вернуть фокус обратно на ссылку для перехода к основному контенту.
- Переместить фокус на заголовок верхнего уровня новой страницы.
Где вы решите поместить фокус, будет зависеть от фреймворка, который вы используете, и контента, который вы хотите предоставить своим пользователям. Это может зависеть от контекста или действия.
Управление состоянием¶
Еще одна область, где JavaScript критически важен для доступности, — это управление состоянием, или когда текущее визуальное состояние компонента или страницы передается пользователю вспомогательных технологий с нарушениями зрения, слепому или слепоглухому пользователю.
Часто состояние компонента или страницы управляется через ARIA-атрибуты, как было представлено в модуле ARIA и HTML. Давайте рассмотрим несколько наиболее распространенных типов ARIA-атрибутов, используемых для помощи в управлении состоянием элемента.
Управление состоянием на уровне компонента¶
В зависимости от содержимого вашей страницы и информации, которая нужна вашим пользователям, есть много состояний ARIA для рассмотрения при передаче информации о компоненте пользователю.
Например, вы можете использовать атрибут aria-expanded
, чтобы сообщить пользователю, развернуто ли выпадающее меню или список, или свернуто.
Или вы можете использовать aria-pressed
, чтобы указать, что кнопка была нажата.
Важно быть избирательным при применении ARIA-атрибутов. Продумайте пользовательский поток, чтобы понять, какая критическая информация должна быть передана пользователю.
Управление состоянием на уровне страницы¶
Разработчики часто используют визуально скрытую область, называемую ARIA live region, для объявления изменений на экране и предупреждающих сообщений пользователям вспомогательных технологий (AT). Эта область может быть связана с JavaScript для уведомления пользователей о динамических изменениях на странице без необходимости перезагрузки всей страницы.
Исторически JavaScript испытывал трудности с объявлением контента в aria-live
и областях оповещений из-за его динамической природы. Асинхронное добавление контента в DOM затрудняет для AT захват области и ее объявление. Чтобы контент был правильно прочитан, live или alert область должна быть в DOM при загрузке, а затем текст может быть динамически заменен.
Если вы используете JavaScript-фреймворк, хорошие новости в том, что почти все из них имеют пакет "live announcer", который делает всю работу за вас и полностью доступен. Нет необходимости беспокоиться о создании live области и решении проблем, описанных в предыдущем разделе.
Вот некоторые live пакеты для распространенных JavaScript-фреймворков:
- React: react-aria-live и react-a11y-announcer
- Angular:
LiveAnnouncer
- Vue: vue-a11y-utils
Современный JavaScript — это мощный язык, который позволяет веб-разработчикам создавать надежные веб-приложения. Это иногда приводит к избыточной инженерии и, как следствие, к недоступным паттернам. Следуя JavaScript-паттернам и советам в этом модуле, вы можете сделать ваши приложения более доступными для всех пользователей.
Особая благодарность Mark Steadman за предоставление дополнительной поддержки этого модуля. Читайте больше его статей о доступности.
Источник — https://web.dev/learn/accessibility/javascript