Навигация с клавиатуры

Одной из важных составляющих современных веб-приложений является поддержка удобной навигации с клавиатуры. Это особенно актуально для приложений, ориентированных на пользователей с ограниченными возможностями или для тех, кто предпочитает использовать клавиатуру вместо мыши. Riot.js, будучи лёгким и гибким фреймворком, предоставляет достаточно возможностей для реализации клавиатурной навигации, позволяя создавать более доступные и удобные интерфейсы.

Основы событий клавиш

Для начала важно понимать, как в Riot.js обрабатываются события клавиш. Это стандартные события браузера, такие как keydown, keypress и keyup, которые могут быть использованы для отслеживания нажатий клавиш. Чтобы привязать обработчик события к элементу в Riot.js, можно использовать директивы. Основной подход заключается в добавлении обработчиков событий непосредственно в шаблон компонента, что позволяет организовать взаимодействие с клавишами на уровне каждого элемента.

Пример:

<my-component>
  <button onkeyd own="{handleKeyDown}">Нажми клавишу</button>
</my-component>

<script>
  export default {
    handleKeyDown(event) {
      if (event.key === 'Enter') {
        console.log('Enter была нажата');
      }
    }
  }
</script>

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

Использование глобальных событий

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

Пример:

<my-component>
  <h1>Навигация с клавиатуры</h1>
  
  <script>
    export default {
      onMounted() {
        window.addEventListener('keydown', this.handleGlobalKeyDown);
      },
      
      onBeforeUnmount() {
        window.removeEventListener('keydown', this.handleGlobalKeyDown);
      },
      
      handleGlobalKeyDown(event) {
        if (event.key === 'ArrowUp') {
          console.log('Нажата стрелка вверх');
        } else if (event.key === 'ArrowDown') {
          console.log('Нажата стрелка вниз');
        }
      }
    }
  </script>
</my-component>

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

Создание компонентов с поддержкой клавиатурной навигации

В Riot.js можно строить более сложные компоненты, в которых поддерживается навигация с помощью клавиатуры, например, в виде списков, вкладок, меню или галерей. Для этих целей можно использовать стандартные события клавиш и манипулировать состоянием компонента, меняя активный элемент в ответ на действия пользователя.

Пример компонента, который реализует навигацию по списку с помощью стрелок:

<keyboard-nav>
  <ul>
    <li each="{item, index in items}" class="{active: index === activeIndex}" tabindex="0">
      {item}
    </li>
  </ul>

  <script>
    export default {
      items: ['Первый', 'Второй', 'Третий', 'Четвертый'],
      activeIndex: 0,

      onMounted() {
        window.addEventListener('keydown', this.handleKeyDown);
      },

      onBeforeUnmount() {
        window.removeEventListener('keydown', this.handleKeyDown);
      },

      handleKeyDown(event) {
        if (event.key === 'ArrowDown') {
          this.activeIndex = (this.activeIndex + 1) % this.items.length;
        } else if (event.key === 'ArrowUp') {
          this.activeIndex = (this.activeIndex - 1 + this.items.length) % this.items.length;
        }
      }
    }
  </script>
</keyboard-nav>

В этом примере список ul содержит несколько элементов, и каждый элемент можно активировать с помощью стрелок вверх и вниз. При этом свойство activeIndex отслеживает индекс активного элемента, а класс active применяется только к активному элементу.

Поддержка фокуса

Когда речь идет о клавиатурной навигации, важно учитывать фокусировку на элементах. Элементы с атрибутом tabindex могут быть активированы с помощью клавиш Tab или Shift+Tab, что позволяет пользователю переключаться между элементами интерфейса. Это особенно полезно при реализации клавиатурной навигации по форме или меню.

В Riot.js можно использовать директиву tabindex для указания порядка навигации, а также управлять фокусом с помощью методов DOM.

Пример:

<focus-nav>
  <input type="text" tabindex="1" placeholder="Имя">
  <input type="text" tabindex="2" placeholder="Фамилия">
  <input type="text" tabindex="3" placeholder="Электронная почта">

  <script>
    export default {}
  </script>
</focus-nav>

Здесь три текстовых поля имеют свойство tabindex, что позволяет переключаться между ними с помощью клавиши Tab.

Обработка специальных клавиш

Некоторые клавиши требуют особого подхода в обработке. Например, клавиши Enter, Escape, Space и другие часто используются для действий, таких как отправка формы, закрытие модальных окон или переключение между состояниями. Чтобы эффективно управлять такими клавишами, необходимо правильно настроить обработчики событий и учитывать особенности их работы.

Пример для обработки клавиши Enter и закрытия окна по клавише Escape:

<modal-dialog>
  <div class="modal">
    <button onkeyd own="{handleKeyDown}">Закрыть</button>
  </div>

  <script>
    export default {
      onMounted() {
        window.addEventListener('keydown', this.handleKeyDown);
      },

      onBeforeUnmount() {
        window.removeEventListener('keydown', this.handleKeyDown);
      },

      handleKeyDown(event) {
        if (event.key === 'Enter') {
          console.log('Окно отправлено');
        } else if (event.key === 'Escape') {
          console.log('Окно закрыто');
        }
      }
    }
  </script>
</modal-dialog>

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

Преимущества использования клавиатурной навигации

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

Кроме того, интеграция таких возможностей в Riot.js с использованием простых директив и событий позволяет быстро добавлять эту функциональность в компоненты, не перегружая код и не усложняя архитектуру приложения.

Riot.js предоставляет инструменты для реализации гибкой и эффективной клавиатурной навигации, что способствует созданию более доступных и удобных веб-приложений.