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

Эта статья посвящена реализации вышеуказанных расширенных возможностей калькулятора, позволяющих сделать его более интерактивным и удобным в использовании. Для тех, кто хочет следовать тому же дизайну и базовой структуре, вот ссылка на оригинальное техзадание: Приложение «Калькулятор» — Frontend Mentor.

Рассмотрим основные шаги по добавлению этих мощных функций!

Опции изменения тем калькулятора

Голосовые команды (Web Speech API)

Чтобы сделать калькулятор более интерактивным, рекомендуется добавить в него удобную функцию — голосовые команды. Используя Web Speech API, можно включить распознавание речи в браузере, позволяя пользователям выполнять вычисления без применения рук. В этом разделе вы узнаете, как реализовать эту функцию с помощью JavaScript.

Что такое Web Speech API?

Web Speech API имеет две ключевые функции:

  • Распознавание речи (Speech Recognition) — преобразование произнесенных слов в текст.
  • Синтез речи (Speech Synthesis) — преобразование текста в речь (в данном руководстве сосредоточимся на функции распознавания речи).

Благодаря интеграции функции распознавания речи, пользователи могут отдавать команды типа «сложить 2 и 3» для выполнения вычислений, что делает работу более динамичной.

Пошаговая реализация

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

1. Проверка поддержки браузера

Прежде чем приступить к работе, убедимся, что браузер пользователя поддерживает Web Speech API.

if (!('webkitSpeechRecognition' in window)) {
  console.error('Speech recognition not available')
  return
}

2. Настройка экземпляра распознавания речи

Инициализируем объект распознавания речи и зададим его свойства (например, настройки языка и результатов).

const recognition = new webkitSpeechRecognition()
recognition.lang = 'en-US' // Настройте язык так, как вам нужно
recognition.continuous = true // Продолжение непрерывного распознавания речи до остановки
recognition.interimResults = true // Предоставление промежуточных результатов во время фиксации речи

3. Активирование распознавания речи

Добавим слушатель событий, чтобы активировать распознавание речи, когда пользователь нажмет на кнопку, например «Start Voice» («Запуск голосовых команд»).

document.getElementById('start-voice').addEventListener('click', () => {
  recognition.start()
})

4. Обработка распознанного текста

Когда речь будет распознана, запускается событие result. Можете обработать этот текст, чтобы выполнить нужную операцию.

recognition.addEventListener('result', (event) => {
const results = Object.values(event.results)

if (results.length) document.getElementById('start-voice').classList.add('listening')

for (const result of results) {
const { transcript } = result[0]
const { isFinal } = result

// Вызовите функцию для обработки команды и выполнения вычислений
// Если вам нужен счет в реальном времени, просто удалите валидацию "Final".
if (isFinal) executeVoiceCommand(transcript.trim())
}
});

5. Обработка ошибок

Не забудьте обработать ошибки, которые могут возникнуть в процессе распознавания.

recognition.addEventListener('error', (event) => {
console.error('Speech recognition error:', event.error)
})

Если предпочитаете более структурированную реализацию с использованием архитектуры, основанной на классах, можете ознакомиться с полным кодом здесь: GitHub — Speak.js.

Клавиши быстрого доступа (keydown-event)

Чтобы сделать калькулятор еще более удобным в использовании, можно добавить поддержку клавиш быстрого доступа. Это позволит пользователям выполнять вычисления без использования мыши, просто нажимая соответствующие клавиши на клавиатуре.

Что такое keydown-event?

Клавиши быстрого доступа (быстрые клавиши) работают путем сопоставления определенных клавиш с действиями в приложении. При нажатии клавиши браузер обнаруживает это событие и запускает соответствующее действие. Для этого используется keydown event (событие нажатия клавиши), которое прослушивает нажатия клавиш на клавиатуре.

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

Пошаговая реализация

Клавиши быстрого доступа в калькуляторе можно разделить на три категории:

  1. Быстрые клавиши действий (Action Shortcuts): вызывают основные действия калькулятора, такие как выполнение вычислений или сброс дисплея.
  1. Быстрые клавиши ввода (Input Shortcuts): позволяют пользователям добавлять значения на дисплей, включая числа и операторы.
  1. Быстрые клавиши тем (Theme Hotkeys): позволяют пользователям менять тему калькулятора одним нажатием клавиши.

Посмотрим, как реализуются эти категории.

Быстрые клавиши действий

getKeyboardActions() {
const keyActions = {
'Enter': () => this.calculate(), // Запуск вычислений
'Backspace': (event) => {
event.preventDefault()
this.handleRemoveLastInput() // Удаление последнего введенного символа
},
'Escape': () => this.resetValue(), // Сброс калькулятора
'Delete': () => this.resetValue() // Также сброс калькулятора
}

return keyActions
}

Эта функция определяет действия, которые должны вызываться определенными клавишами:

  • Enter запускает вычисление текущего ввода;
  • Backspace удаляет последний символ из текущего ввода;
  • Escape и Delete сбрасывают результаты работы калькулятора, очищая текущий ввод или память.

Необходимо настроить слушателя событий, который будет слушать события от нажатия клавиш и обрабатывать действия соответствующим образом.

Быстрые клавиши тем

При выборе опции «Темы» пользователь может нажать клавишу на клавиатуре, чтобы сохранить ее в качестве быстрой клавиши темы. Затем эта клавиша ассоциируется с темой с помощью двух атрибутов: data-chosen-key и data-key. В атрибуте data-chosen-key хранится нажатая клавиша, а в data-key — уникальный идентификатор темы. Это позволяет пользователям привязать определенную клавишу к теме, что упрощает переключение между темами с помощью быстрых клавиш.

Интеграция быстрых клавиш всех типов в событии keydown

document.addEventListener('keydown', (event) => {
const keyActions = calculator.getKeyboardActions()

if (keyActions[event.key]) {
keyActions[event.key](event) // Выполнение быстрых клавиш действий
} else if ('0123456789+-*/.'.includes(event.key)) {
calculator.handleAddInput(event.key) // Выполнение быстрых клавиш ввода
}

// Выполнение горячих клавиш тем:
const themeId = themeManager.getThemeIdByKey(event.key)
if (themeId) themeManager.changeThemeById(themeId)
})

Здесь рассмотрена только базовая концепция быстрых клавиш. Чтобы изучить полную реализацию, ознакомьтесь с полным кодом: GitHub — themeManager.js.

Адаптивные темы (prefer-color-scheme)

Отличной возможностью повысить качество пользовательского опыта является включение адаптивных тем, основанных на системных предпочтениях пользователя. Медиа-запрос prefers-color-scheme позволяет автоматически переключаться между светлой и темной темами. В этом разделе рассказывается, как реализовать эту функцию, используя только JavaScript.

Что такое prefers-color-scheme?

Медиа-запрос prefers-color-scheme определяет, какую тему — светлую или темную — предпочитает пользователь в своей операционной системе или браузере. Прослушивание этого запроса позволяет применить соответствующую тему, не требуя ввода данных пользователем.

Пошаговая реализация

Вот как реализовать адаптивные темы с помощью JavaScript и CSS.

1. Определение конфигурации тем

В constants/themes.js определяем темы с уникальными идентификаторами и переменными цвета:

export const themesConfig = {
'Default': { id: '1', colors: [{ name: '--background', value: '#3a4764' }] },
'Light': { id: '2', colors: [{ name: '--background', value: '#e6e6e6' }] },
'Dark': { id: '3', colors: [{ name: '--background', value: '#17062a' }] }
}

2. Определение системных предпочтений 

Используем window.matchMedia, чтобы узнать, какой режим — светлый или темный — предпочитает пользователь:

function setPreferColorSchemeTheme() {
if (!window.matchMedia) return

Object.keys(themesConfig).forEach(themeName => {
const isPreferred = window.matchMedia(`(prefers-color-scheme: ${themeName})`).matches
if (isPreferred) btnTheme.value = this.themesConfig[themeName].id // Обновление кнопки темы новой темой
})

this.changeThemeById(btnTheme.value) // Применение новой темы с новым текущим значением
}

3. Применение выбранной темы

Когда предпочтение обнаружено, обновляем тему с помощью changeThemeById:

function applyTheme(themeColors) {
themeColors.forEach(({ name, value }) => {
root.style.setProperty(name, value)
})
}

function changeThemeById(themeId) {
const theme = Object.values(themesConfig).find(theme => theme.id === themeId)
if (!theme) return

btnTheme.value = theme.id
applyTheme(theme.colors)
}

Заключение

Теперь вы знаете, как расширить возможности простого калькулятора, добавив в него такие дополнительные функции, как голосовые команды, клавиши быстрого доступа и адаптивные темы — и все это с помощью чистого JavaScript. Использование встроенных веб-интерфейсов API и эффективных методов написания кода позволит вам улучшать пользовательский опыт, делая его динамичным и настраиваемым.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Igorcbraz: Build a Feature-Rich Calculator with Pure JS

Предыдущая статьяRxSignals: самая мощная синергия в истории Angular 
Следующая статьяC++: подробное руководство по вложенным операторам If-Else