aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html')
-rw-r--r--files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html206
1 files changed, 206 insertions, 0 deletions
diff --git a/files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html b/files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html
new file mode 100644
index 0000000000..00b91b8257
--- /dev/null
+++ b/files/ru/web/accessibility/keyboard-navigable_javascript_widgets/index.html
@@ -0,0 +1,206 @@
+---
+title: Навигация с клавиатуры в JavaScript
+slug: Web/Accessibility/Keyboard-navigable_JavaScript_widgets
+tags:
+ - Accessibility
+ - DOM
+translation_of: Web/Accessibility/Keyboard-navigable_JavaScript_widgets
+---
+<p class="seoSummary">Как сделать для JavaScript-виджетов на основе span или div возможность навигации с клавиатуры.</p>
+
+<h3 id="Обзор">Обзор</h3>
+
+<p>Веб-приложения часто используют JavaScript, чтобы имитировать работу различных элементов, перешедших в веб с десктопных приложений: динамические меню, закладки, нестандартные элементы форм. Все эти элементы можно назвать виджетами. В вёрстке виджеты обычно состоят из набора HTML-элементов {{HTMLElement("div")}} и {{HTMLElement("span")}}, которые по умолчанию не предоставляют возможности работать с ними, используя клавиатуру. В данной статье описывается техника, позволяющая сделать JS-виджеты управляемыми с клавиатуры.</p>
+
+<h3 id="Использование_tabindex">Использование tabindex</h3>
+
+<p>Атрибут <code>tabindex</code> был представлен в спецификации HTML 4. Он позволяет задать порядок, в котором элементы будут получать фокус при навигации с клавиатуры. Текущая реализация, описанная в HTML 5 draft specs, довольно сильно отличается от первоначальной. Все распространённые браузеры теперь придерживаются новой спецификации.</p>
+
+<p>В данной таблице описано поведение элементов в зависимости от значения атрибута <code>tabindex</code>:</p>
+
+<table class="fullwidth-table" style="width: 75% !important;">
+ <tbody>
+ <tr>
+ <th>Атрибут <code>tabindex</code></th>
+ <th>
+ <p>Фокус при помощи мыши или программно через <code>element.focus()</code></p>
+ </th>
+ <th>Фокус при навигации с клавиатуры (Tab)</th>
+ </tr>
+ <tr>
+ <td>Отсутствует</td>
+ <td>Работает согласно правилам платформы для конкретного элемента (возможен для элементов форм, ссылок и т.п.)</td>
+ <td>Работает согласно правилам платформы для конкретного элемента</td>
+ </tr>
+ <tr>
+ <td>Менее нуля (<code>tabindex="-1"</code>)</td>
+ <td>Возможен</td>
+ <td>Невозможен. Разработчик должен использовать <code><a href="/ru/DOM/Element.focus">focus()</a></code> при нажатии стрелочек на клавиатуре и других клавиш.</td>
+ </tr>
+ <tr>
+ <td>Нуль (<code>tabindex="0"</code>)</td>
+ <td>Возможен</td>
+ <td>Происходит поочередно, исходя из позиции элемента внутри документа</td>
+ </tr>
+ <tr>
+ <td>Более нуля (например <code>tabindex="33"</code>)</td>
+ <td>Возможен</td>
+ <td>Значение атрибута <code>tabindex</code> указывает очередность, в которой элемент получит фокус. Чем меньше значение атрибута, тем раньше элемент получит фокус. В любом случае, фокус придет на такие элементы раньше, чем на элементы с <code>tabindex="0"</code> и элементы, которые способны получить фокус без атрибута <code>tabindex</code> (например, <code>tabindex="7"</code> получит фокус раньше <code>tabindex="11"</code>)</td>
+ </tr>
+ </tbody>
+</table>
+
+<h4 id="Простые_контролы">Простые контролы</h4>
+
+<p>Чтобы сделать простой виджет доступным через клавишу Tab, задайте <code>tabindex="0"</code> на HTML элементах {{HTMLElement("div")}} или {{HTMLElement("span")}}, из которых он состоит. Ниже представлен пример эмулирования чекбоксов. Вместо элементов input в примере используется {{HTMLElement("span")}}.</p>
+
+<p><em>Пример 1: Простой виджет, эмулирующий работу чекбосов путем смены изображений. Виджет использует tabindex, чтобы обеспечить доступ с клавиатуры.</em></p>
+
+<pre class="brush: html">&lt;!-- Без атрибута tabindex, элементы &lt;span&gt; не смогут принимать фокус с клавиатуры --&gt;
+&lt;div&gt;
+  &lt;span role="checkbox" aria-checked="true" tabindex="0"&gt;
+  &lt;img src="checked.gif" role="presentation" alt="" /&gt;
+  Добавить декоративную корзину с фруктами
+  &lt;/span&gt;
+&lt;/div&gt;
+&lt;div&gt;
+  &lt;span role="checkbox" aria-checked="true" tabindex="0"&gt;
+  &lt;img src="checked.gif" role="presentation" alt="" /&gt;
+  Добавить поющую телеграмму
+  &lt;/span&gt;
+&lt;/div&gt;
+&lt;div&gt;
+  &lt;span role="checkbox" aria-checked="false" tabindex="0"&gt;
+  &lt;img src="unchecked.gif" role="presentation" alt="" /&gt;
+  С предоплатой
+  &lt;/span&gt;
+&lt;/div&gt;
+</pre>
+
+<h4 id="Сгруппированные_контролы">Сгруппированные контролы</h4>
+
+<p>Безусловно есть необходимость создания более сложных виджетов. В качестве примеров можно привести меню, панели табов, различные динамические таблицы, представления для информации, имеющей древовидную структуру. Для таких контролов родительский элемент должен иметь атрибут <code>tabindex="0"</code>. В таком случае он сможет попасть в фокус с клавиатуры. Все дочерние элменты (пункты меню, отдельные табы, ячейки, строки) должны иметь <code>tabindex="-1"</code>, чтобы не попадать в фокус при нажатии tab. Пользователи должны иметь возможность путешествовать по дочерним элементам при помощи стрелочек на клавиатуре.</p>
+
+<p>Ниже приведен пример, который демонстрирует использование этой техники для реализации вложенного меню. После того, как в фокус попадает основной элемент меню ({{HTMLElement("ul")}}), разработчик должен программно управлять фокусом, реагируя на нажития клавиш со стрелочками. Для описания техники управления фокусом внутри виджета смотрите раздел «Управление фокусом внутри виджета» ниже в данной статье.</p>
+
+<p><em>Пример 2: Меню, использующее атрибут tabindex для осуществления доступа с клавиатуры</em></p>
+
+<pre class="brush: html">&lt;ul id="mb1" tabindex="0"&gt;
+ &lt;li id="mb1_menu1" tabindex="-1"&gt; Шрифт
+ &lt;ul id="fontMenu" title="Шрифт" tabindex="-1"&gt;
+ &lt;li id="sans-serif" tabindex="-1"&gt;Sans-serif&lt;/li&gt;
+ &lt;li id="serif" tabindex="-1"&gt;Serif&lt;/li&gt;
+ &lt;li id="monospace" tabindex="-1"&gt;Monospace&lt;/li&gt;
+ &lt;li id="fantasy" tabindex="-1"&gt;Fantasy&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/li&gt;
+ &lt;li id="mb1_menu2" tabindex="-1"&gt; Стиль
+ &lt;ul id="styleMenu" title="Стиль" tabindex="-1"&gt;
+ &lt;li id="italic" tabindex="-1"&gt;Наклонный&lt;/li&gt;
+ &lt;li id="bold" tabindex="-1"&gt;Жирный&lt;/li&gt;
+ &lt;li id="underline" tabindex="-1"&gt;Подчеркнутый&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/li&gt;
+ &lt;li id="mb1_menu3" tabindex="-1"&gt; Выравнивание
+ &lt;ul id="justificationMenu" title="Выравнивание" tabindex="-1"&gt;
+ &lt;li id="left" tabindex="-1"&gt;Слева&lt;/li&gt;
+ &lt;li id="center" tabindex="-1"&gt;По центру&lt;/li&gt;
+ &lt;li id="right" tabindex="-1"&gt;Справа&lt;/li&gt;
+ &lt;li id="justify" tabindex="-1"&gt;По ширине&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/li&gt;
+&lt;/ul&gt;</pre>
+
+<h4 id="Неактивные_(disabled)_контролы">Неактивные (disabled) контролы</h4>
+
+<p>Когда элемент управления становится неактивным, он должен не попадать в фокус при нажатии на tab, что обеспечивается выставлением у элемента атрибута <code>tabindex="-1"</code>. Обратите внимание, что неактивные элементы в пределах сгруппированного виджета (такие как, подпункты меню ) должны иметь возможность быть выбранными при помощи стрелочек на клавиатуре.</p>
+
+<h3 id="Управление_фокусом_внутри_виджета">Управление фокусом внутри виджета</h3>
+
+<p>Когда пользователь уходит с виджета, а потом возвращается обратно, фокус должен вернутся на определенный элемент, у которого был фокус раньше. Например, на конкретный элемент дерева или ячейку. Есть два варианта, которыми этого можно добиться:</p>
+
+<ol>
+ <li>Переходящий <code>tabindex</code>: програмное перемещение фокуса</li>
+ <li><code>aria-activedescendant</code>: управление «виртуальным» фокусом</li>
+</ol>
+
+<h4 id="Техника_первая_Переходящий_tabindex">Техника первая: Переходящий tabindex</h4>
+
+<p>Идея данной техники заключается в выставлении атрибута <code>tabindex</code> в нулевое значение для элемента, который последним находился в фокусе. При этом если пользователь уйдет табом с виджета, а потом вернется обратно, элемент восстановит фокус правильно. Заметьте, что выставляя <code>tabindex</code> в "0", необходимо выставлять <code>tabindex="-1"</code> для предыдущего выделенного элемента. Эта техника требует выставлять фокус элементам программно, реагируя на нажатие клавиш.</p>
+
+<p>Для этого необходимо слушать событие keydown для каждого дочернего элемента виджета. Когда пользователь нажимает на стрелочки на клавиатуре, чтобы переместиться на другой элемент следует:</p>
+
+<ol>
+ <li>программно применить фокус к другому элементу</li>
+ <li>изменить tabindex элемента в фокусе на 0</li>
+ <li>изменить tabindex предыдущего элемента на -1</li>
+</ol>
+
+<p>По ссылке Вы можете увидеть пример <a href="https://files.paciellogroup.com/training/WWW2012/samples/Samples/aria/tree/index.html">WAI-ARIA tree view</a>, использующий эту технику.</p>
+
+<h5 id="Советы">Советы</h5>
+
+<h6 id="Используйте_element.focus()_чтобы_задать_фокус_элементу">Используйте element.focus() чтобы задать фокус элементу</h6>
+
+<p>Не используйте <code>createEvent()</code>, <code>initEvent()</code> and <code>dispatchEvent()</code> чтобы задать фокус. Событие DOM focus должно использовать только для получения информации о том, что произошел фокус на элемент, оно генерируется системой, когда какой-либо элемент попал в фокус. Оно не должно использовать для того, чтобы задать фокус. Вместо этого используйте <code>element.focus()</code>.</p>
+
+<h6 id="Используйте_событие_onfocus_чтобы_отслеживать_фокус">Используйте событие onfocus чтобы отслеживать фокус</h6>
+
+<p>При разработке не стоит расчитывать, что фокус будет меняться только в следствие манипуляций пользователя с клавиатурой и мышью. Вспомогательные программы, такие как screen readers могут задавать фокус элементам. Отслеживайте события <code>onfocus</code> и <code>onblur</code>, вместо событий мыши и клавиатуры.</p>
+
+<p><code>onfocus</code> и <code>onblur могут быть использованы с любыми елементами.</code> Сейчас в стандартах не описано метода для получения элемента, находящегося в фокусе. Поэтому если вам потребуется отслеживать элемент с фокусом, его надо будет запоминать в переменную.</p>
+
+<h4 id="Техника_вторая_aria-activedescendant">Техника вторая: aria-activedescendant</h4>
+
+<p>Эта техника позволяет объединить  каждый отдельно взятый обработчик  событий в контейнер графического элемента и использовать  <code>aria-activedescendent</code> для слежения за "виртуальным" фокусом . (Для получения более подробной информации относительно ARIA обратите внимание на  <a href="/ru/docs/Web/Accessibility/An_overview_of_accessible_web_applications_and_widgets">обзор доступных веб-приложений и виджетов </a>.)</p>
+
+<p>The <code>aria-activedescendant</code> property identifies the ID of the descendent element that currently has the virtual focus. The event handler on the container must respond to key and mouse events by updating the value of <code>aria-activedescendant</code> and ensuring that the current item is styled appropriately (for example, with a border or background color). See the source code of this <a href="https://www.oaa-accessibility.org/example/28/">ARIA radiogroup example</a> for a direct illustration of how this works.</p>
+
+<h5 id="Tips">Tips</h5>
+
+<h6 id="scrollIntoView">scrollIntoView</h6>
+
+<p>Note that the use of this pattern requires the author to ensure that the current <em>focused</em> widget is scrolled into view. You should be able to use the {{domxref("element.scrollIntoView()")}} function, but we recommend confirming this works for you in your target browsers using the <a href="https://www.quirksmode.org/dom/tests/scrollintoview.html">quirksmode test</a>.</p>
+
+<h6 id="Issues">Issues</h6>
+
+<ul>
+ <li><a href="https://www.quirksmode.org/dom/w3c_cssom.html">quirksmode reports problems in Opera, and Konqueror</a></li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=450405">Firefox 3.0.1 introduced bug</a></li>
+</ul>
+
+<h3 id="Рекомендации">Рекомендации</h3>
+
+<h4 id="Используйте_onkeydown_для_отлова_событий_вместо_onkeypress">Используйте onkeydown для отлова событий вместо onkeypress</h4>
+
+<p>В IE событие <code>keypress</code> срабатывает только для буквенно-цифровых клавиш. Используйте <code>onkeydown</code> вместо этого.</p>
+
+<h4 id="Убедитесь_что_клавиатура_и_мышь_производят_одинаковое_действие">Убедитесь, что клавиатура и мышь производят одинаковое действие</h4>
+
+<p>Чтобы обеспечить независимый от устройства ввода механизм взаимодействия с пользователем, обработчики событий мыши и клавиатуры должны совместно использовать код там, где это необходимо. Например, код, который обновляет значение <code>tabindex</code> или стили, когда пользователь переключается между элементами c помощью стрелок, должен выполняться и обработчиками клика мыши, чтобы применить те же самые изменения.</p>
+
+<h4 id="Убедитесь_что_можно_использовать_клавиатуру_для_активации_элемента">Убедитесь, что можно использовать клавиатуру для активации элемента </h4>
+
+<p>Чтобы обеспечить использование клавиатуры для активации элемента, любые обработчики событий мыши должны быть также связаны с событиями клавиатуры. Например, чтобы клавиша Enter активировала элемент, если у вас есть <code>onclick="doSomething()"</code>, вам необходимо также связать <code>doSomething()</code> с событием нажатия клавиши: <code>onkeydown="return event.keyCode != 13 || doSomething();"</code>.</p>
+
+<h4 id="Не_используйте_focus_для_стилизации_фокусировки_(если_вы_поддерживаете_IE_7_и_более_ранние)">Не используйте :focus для стилизации фокусировки (если вы поддерживаете IE 7 и более ранние)</h4>
+
+<p>IE 7 и более ранние версии не поддерживают <code>:focus</code> псевдо-селектор; не используйте его для стилизации фокуса. Вместо этого, установите стили с помощью обработчика событий <code>onfocus</code>, например, добавив название CSS стиля аттрибуту <code>class</code>.</p>
+
+<h4 id="Always_draw_the_focus_for_tabindex-1_items_and_elements_that_receive_focus_programatically">Always draw the focus for tabindex="-1" items and elements that receive focus programatically</h4>
+
+<p>IE will not automatically draw the focus outline for items that programatically receive focus. Choose between changing the background color via something like <code>this.style.backgroundColor = "gray";</code> or add a dotted border via <code>this.style.border = "1px dotted invert"</code>. In the dotted border case you will need to make sure those elements have an invisible 1px border to start with, so that the element doesn't grow when the border style is applied (borders take up space, and IE doesn't implement CSS outlines).</p>
+
+<h4 id="Prevent_used_key_events_from_performing_browser_functions">Prevent used key events from performing browser functions</h4>
+
+<p>If your widget handles a key event, prevent the browser from also handling it (for example, scrolling in response to the arrow keys) by using your event handler's return code. If your event handler returns <code>false</code>, the event will not be propagated beyond your handler.</p>
+
+<p>For example:</p>
+
+<pre class="brush: html">&lt;span tabindex="-1" onkeydown="return handleKeyDown();"&gt;</pre>
+
+<p>If <code>handleKeyDown()</code> returns <code>false</code>, the event will be consumed, preventing the browser from performing any action based on the keystroke.</p>
+
+<h4 id="Don't_rely_on_consistent_behavior_for_key_repeat_at_this_point">Don't rely on consistent behavior for key repeat, at this point</h4>
+
+<p>Unfortunately <code>onkeydown</code> may or may not repeat depending on what browser and OS you're running on.</p>