Клавиатурная навигация является критическим элементом доступности веб-приложений. Inferno предоставляет возможность эффективного управления фокусом и событиями клавиатуры, что позволяет создавать интерфейсы, удобные для пользователей с различными потребностями.
В Inferno работа с клавиатурой строится на стандартных DOM-событиях:
onKeyDown, onKeyUp и onKeyPress.
Отличие фреймворка заключается в высокой производительности при
обработке большого количества компонентов и минимальных задержках при
изменении состояния компонентов, что особенно важно для интерактивных
элементов, таких как формы, таблицы и навигационные меню.
import { render } from 'inferno';
import { Component } from 'inferno-component';
class KeyboardComponent extends Component {
handleKeyDown = (event) => {
switch(event.key) {
case 'Enter':
console.log('Нажата клавиша Enter');
break;
case 'ArrowUp':
console.log('Стрелка вверх');
break;
case 'ArrowDown':
console.log('Стрелка вниз');
break;
}
}
render() {
return (
<div tabIndex={0} onKeyD own={this.handleKeyDown}>
Фокусируемый элемент
</div>
);
}
}
render(<KeyboardComponent />, document.getElementById('app'));
Ключевые моменты:
tabIndex={0} делает элемент фокусируемым с
клавиатуры.switch или условных конструкций позволяет
эффективно обрабатывать разные клавиши.Для обеспечения корректной клавиатурной навигации необходимо грамотно
управлять фокусом. Inferno не предоставляет встроенных хуков,
аналогичных React useRef в функциональных компонентах,
однако в классовых компонентах можно использовать прямые ссылки на
DOM-элементы через ref.
class FocusComponent extends Component {
inputRef = null;
setFocus = () => {
if (this.inputRef) {
this.inputRef.focus();
}
}
render() {
return (
<div>
<input ref={el => this.inputRef = el} type="text" />
<button onCl ick={this.setFocus}>Установить фокус</button>
</div>
);
}
}
Важные моменты:
ref сохраняет ссылку на DOM-элемент для последующего
управления.focus().Для поддержки пользователей с ограниченными возможностями необходимо применять ARIA-атрибуты. Inferno позволяет напрямую добавлять эти атрибуты к компонентам без дополнительного оборачивания.
<div role="menu" aria-label="Главное меню">
<button role="menuitem" tabIndex={0}>Пункт 1</button>
<button role="menuitem" tabIndex={0}>Пункт 2</button>
</div>
Ключевые моменты:
role определяет семантику элемента для вспомогательных
технологий.aria-label задаёт описание элемента, которое
озвучивается экранными читалками.tabIndex обеспечивает последовательность перехода по
клавиатуре.Для компонентов типа списков, таблиц и деревьев часто требуется реализовать циклическую навигацию. Это можно сделать через отслеживание текущего индекса и изменения фокуса на следующий элемент при нажатии стрелок.
class ListNavigation extends Component {
state = { focusedIndex: 0 };
handleKeyDown = (event) => {
const { focusedIndex } = this.state;
const maxIndex = this.items.length - 1;
if(event.key === 'ArrowDown') {
this.setState({ focusedIndex: focusedIndex === maxIndex ? 0 : focusedIndex + 1 });
}
if(event.key === 'ArrowUp') {
this.setState({ focusedIndex: focusedIndex === 0 ? maxIndex : focusedIndex - 1 });
}
}
items = ['Элемент 1', 'Элемент 2', 'Элемент 3'];
render() {
return (
<ul tabIndex={0} onKeyD own={this.handleKeyDown}>
{this.items.map((item, index) => (
<li key={index} className={this.state.focusedIndex === index ? 'focused' : ''}>
{item}
</li>
))}
</ul>
);
}
}
Особенности:
focusedIndex управляет визуальной подсветкой
и логикой фокуса.ref для корректного взаимодействия с экранными
читалками.Inferno позволяет реализовывать кастомные сочетания клавиш, что полезно для ускоренного взаимодействия с приложением.
handleShortcut = (event) => {
if(event.ctrlKey && event.key === 's') {
event.preventDefault();
console.log('Сохранение через Ctrl+S');
}
}
Особенности:
event.ctrlKey, event.altKey,
event.shiftKey помогают отслеживать модификаторы.preventDefault() предотвращает стандартное действие
браузера.Для доступности важно, чтобы пользователи могли видеть, какой элемент находится в фокусе. Inferno позволяет легко динамически менять классы для подсветки элементов:
<li className={this.state.focusedIndex === index ? 'focused' : ''}>
Рекомендации:
Хотя клавиатурная навигация ориентирована на десктопы, важно сохранять совместимость с сенсорными экранами:
tabIndex остаются доступными для фокусировки
при использовании внешней клавиатуры.