Программа чтения с экрана NVDA не переключается в режим фокусировки предсказуемо

У меня есть простой фрагмент кода, который я пытаюсь сделать доступным с клавиатуры при использовании программы чтения с экрана NVDA.

В частности, у меня есть div с ролью «кнопки», в который вложен другой div с другой ролью «кнопки». У каждого div есть свое событие onkeydown, которое запускается, когда пользователь переходит к этому div и нажимает «ввод».

Эта функциональность клавиатуры работает должным образом, когда у меня не включена программа чтения с экрана NVDA.

Однако, когда у меня включена программа чтения с экрана, вложенное событие нажатия клавиши больше не срабатывает. Вместо этого запускается только родительское событие, даже если вложенное событие имеет фокус.

Однако, если я вручную переведу NVDA из «режима просмотра» в «режим фокусировки» (нажатием клавиши NVDA + пробел), то ключевые события снова будут работать по желанию.

К сожалению, для меня неприемлемо ожидать, что кто-то, использующий NVDA, узнает о ручном переключении в «режим фокусировки». Ему либо необходимо автоматически переключиться в «режим фокусировки», либо он должен работать в «режиме просмотра».

Вот код:

HTML:

<div role="button" 
   tabindex="1" 
   onkeydown="keyEvent(event, outerDivAction)"
   class="outerDiv">
   Outer Div

   <div role="button" 
     tabindex="1"
     onkeydown="keyEvent(event, innerDivAction)"
     class="innderDiv">
     Inner Div</div>
   </div>

<div class="result"></div>

JavaScript:

function outerDivAction(event) {
  event.stopPropagation();
  console.log('outer div');
   $('.result').html('<p>outer div!</p>');
}

function innerDivAction(event) {
  event.stopPropagation();
  console.log('inner div')
  $('.result').html('<p>inner div!</p>');
}

function keyEvent(event, callback) {
  event.stopPropagation();
  if (event.which === 13) {
    callback(event);
  }
}

$('.outerDiv').click(outerDivAction);

$('.innderDiv').click(innerDivAction);

Вы также можете просмотреть код здесь: http://codepen.io/jennEDVT/pen/Yprova

Любая помощь, которую может предложить любой, будет принята с благодарностью!

p.s. Я знаю, что если я возьму вложенный div и перемещу его так, чтобы он больше не был вложенным, а скорее был братом первого div, тогда все будет работать так, как нужно. К сожалению, это не вариант. Div необходимо вложить.


person jennEDVT    schedule 29.11.2016    source источник


Ответы (2)


Это не ошибка NVDA.

Во-первых, у вас не может быть вложенных интерактивных элементов. В частности, нельзя иметь вложенное интерактивное содержимое. Вы не можете вкладывать ссылки и кнопки. Вы не можете вкладывать ссылки в кнопки, и вы не можете вкладывать кнопки в ссылки. Существуют и другие виды интерактивного контента, на которые стоит обратить внимание в будущем. ссылка тоже.

Вы можете обнаружить, что ваш код технически действителен, но это только потому, что то, что вы написали, является выдумкой.

Вместо использования правильного элемента (<button>) вы выбрали role=button на <div>s. Валидатор HTML передаст ваш код, потому что он допустим для вложения <div>.

Однако, давая им каждый role=button, вы проинструктировали пользовательский агент рассматривать их как <button> (за вычетом всех связанных с ними преимуществ, таких как доступность, обработчики ключей, семантика и т. Д.).

Теперь давайте вернемся и снова проверим этот код, как его увидит пользовательский агент (как вложенные <button>s). Проверка HTML W3C Nu не удалась (я знаю, потому что запускал тест):

Ошибка: начальный тег button виден, но элемент того же типа уже открыт.

Мое предложение:

  • чтобы не гнездить их,
  • преобразовать их в <button>s,
  • удалите недопустимый tabindex=1 (который вам не понадобится),
  • удалите проверку ключевого кода, поскольку <button> дает вам это бесплатно (включая символ 32),
  • превратите ваш <div class="result"> в живой регион ARIA (есть несколько советов здесь),
  • и оберните кнопки оберткой, чтобы получить желаемый визуальный эффект.

Пример измененного кода:

 <div class="wrapper">
   <button class="outerDiv">
     Outer Div
   </button>
   <button class="innderDiv">
     Inner Div
   </button>
 </div>

 <div class="result" role="alert" aria-live="assertive"></div>
person aardrian    schedule 30.11.2016
comment
Спасибо, что нашли время дать такое исчерпывающее объяснение. К сожалению, это будет сложно реализовать, поскольку фактическая спецификация, которую я разрабатываю, представляет собой навигацию с некоторыми элементами, с которыми связаны выпадающие меню, а затем выпадающие элементы имеют дополнительное подменю, отображаемое в виде всплывающего меню. И каждый из этих элементов иногда может быть кнопками (открывающими подменю) или ссылками, поэтому в настоящее время я использую JavaScript для их динамического изменения с role = button на role = link. Причина, по которой элементы вложены, заключается в том, что подменю являются дочерними по отношению к родительским элементам. - person jennEDVT; 30.11.2016
comment
Чтобы избежать вложенности кнопок, не могли бы вы реструктурировать свой код, чтобы использовать список с вложенными подсписками (которые содержат кнопки)? Требуется немного больше усилий для управления видимостью на основе фокуса элементов списка (или переключателя кнопок), но это позволяет избежать вложенного интерактивного содержимого, о котором упоминал @aardrian. Вот код, чтобы проиллюстрировать, что я имею в виду: codepen.io/anon/pen/KNyZYm - person Skerrvy; 30.11.2016
comment
@jennEDVT, у вас может быть небольшой выбор, кроме рефакторинга, поскольку вы всегда будете сталкиваться с проблемами со вспомогательными технологиями. У Skerrvy есть хорошая быстрая демонстрация того, что вы можете попробовать. Также ищите существующие шаблоны, которые вы можете изменить. Например, у Adobe есть сложное мегаменю, которое, хотя и слишком много для большинства сайтов, может подойти? adobe-accessibility.github.io/Accessible-Mega-Menu - person aardrian; 30.11.2016
comment
Спасибо за все предложения, а также за ресурсы, на которые стоит обратить внимание. Похоже, нужно провести рефакторинг. - person jennEDVT; 30.11.2016

Если это может вас заинтересовать, WAI-ARIA Authoring Practices (APG) содержит руководство о том, как чтобы сделать доступными различные шаблоны проектирования. Он также включает в себя то, что вы описываете: Меню или строка меню, которая включает код примеры меню с подменю.

person Michiel Bijl    schedule 01.12.2016
comment
Пожалуйста, отредактируйте код, который поможет OP в вашем ответе. Ответы только по ссылке (имеется в виду любой ответ, в котором само решение представлено в виде ссылки и не объясняется в самом сообщении, даже если присутствует другой текст, не связанный с ссылкой), как правило, не одобряются, потому что они могут быть признаны недействительными, если ссылка идет вниз, и в прошлом использовались для саморекламы. - person Justin Time - Reinstate Monica; 01.12.2016
comment
Спасибо за ресурсы! - person jennEDVT; 02.12.2016