Лабораторна робота · Віджет Б

Зберіть свою
ідеальну каву

Оберіть основу, молоко та топпінги — калорійність і ціна розрахуються миттєво. Захищений від некоректних введень.

Конструктор напою

200 мл
50 млЕспресоАмерикано500 мл



Ваш напій

Ваш напій
Еспресо
Еспресо 2 ккал
Молоко 0 ккал
Топпінги 0 ккал
Піна ~5 ккал

Калорійність
7ккал
Об'єм
200мл
35
грн

QA-журнал: виявлені баги та виправлення

Bug Порожнє поле → NaN ккал

При очищенні поля об'єму parseInt("") повертав NaN. Калорійність відображала NaN ккал, ціна також ламалась.

Fix Слайдер замість вводу

Замінено числове поле на <input type="range">. Слайдер гарантує лише валідні значення в діапазоні 50–500 мл — NaN неможливий.

Bug Від'ємний об'єм через JS

При прямій маніпуляції DOM (DevTools) можна було встановити від'ємний об'єм. Калькулятор давав від'ємні калорії — абсурдний результат.

Fix Defensive Guard: min/max clamp

Перед розрахунком: vol = Math.max(50, Math.min(500, vol)). Будь-яке значення поза діапазоном автоматично «затискається» до меж.

Bug Дробові значення кроку

Без step слайдер міг повертати 123.4567 мл — UI показував дріб замість цілого числа.

Fix step="10" + Math.round()

Атрибут step="10" обмежує крок до 10 мл. Додатково застосовується Math.round() як другий захисний рівень.

Bug Немає вибору основи → ціна 0

Якщо програмно зняти всі radio-кнопки, querySelector(':checked') повертав null → TypeError у консолі, ціна падала до 0 грн.

Fix Fallback значення за замовчуванням

Оператор ?.dataset ?? '35' — якщо елемент null, беремо дефолтну ціну еспресо. Консоль залишається чистою.