Перша помилка: Велика суперечка про div
Все почалося з моєї амбітної спроби створити калькулятор. Мені знадобилася ціла година, щоб завершити фронтенд—так, ціла година!
ДИСКЛЕЙМЕР: На той момент я вже п’ять місяців вивчав фронтенд-розробку і був переконаний, що можу стати наступним великим веб-розробником. Спойлер: я не став.
Ось де я застряг. Я не міг зрозуміти, чому div калькулятора не хоче знаходитися під тегом h1. Я пильно дивився на код, як детектив, що розкриває справу, і лише пізніше зрозумів, що теги h1 за замовчуванням є блочними елементами.
Навіть коли я намагався зробити їх інлайн, мій геніальний мозок забув про flex-direction: row, який був застосований до body. Рішення? Потрібно було змінити напрямок flex на column
.
Ось і все! Успіх.
Друга боротьба: Кнопки та дурниці в голові
Далі я взявся за те, щоб зробити кнопки функціональними. Я знав, як використовувати addEventListener
(прослуховувач подій (Event Listener)), тому вирішив, що додавання inline onclick
події безпосередньо в HTML не зашкодить. Це дозволило мені передавати функцію щоразу, коли кнопка натискалася. Все йшло добре.
Додати кнопку "Очистити все" — готово. Дуже просто. Просто стерти все на екрані. Я відчував себе непереможним.
Але потім з'явилася функція "Видалити останню цифру". Мій надмірно впевнений мозок сказав: “Пфф, це буде дуже легко.” Спойлер: це не було легко.
Моя перша спроба була настільки поганою, що будь-який досвідчений JavaScript-розробник сміявся б так сильно, що йому довелося б лягти на відпочинок.
Ось що я вважав геніальним, але насправді це була повна плутанина:
function number(x) {
box.value += x;
const clear = document.querySelector("#c");
clear.addEventListener("click", () => {
box.value = "";
});
const clr = document.querySelector("#x");
clr.addEventListener("click", () => {
box.value = Math.floor(box.value / 10);
});
}
Пекло налагодження
Я натискаю “7”, і моя логіка успішно видаляє “7”. Але коли я намагався очистити наступну цифру, все очищалося. Я плакав всередині. Тоді я помітив, що функція виконувала математичну операцію постійно.
Чому?
Ми зможемо з'ясувати це за допомогою налагодження.
function number(x){
box.value+=x;
const clear=document.querySelector("#c")
clear.addEventListener("click",() => {
box.value=""
})
const clr=document.querySelector("#x")
clr.addEventListener("click",() => {
let remove=Math.floor(box.value / 10);
console.log("remove",remove)
console.log(box.value)
box.value=remove
})
}
За допомогою численних console.log
я з’ясував, чому все очищалося, а на виході з’являлося 0. Причина була в тому, що прослуховувач події clear
(Event Listener) був всередині функції number()
, яка викликалася кожного разу, коли я натискав цифру. Помилка новачка.
Виправлення
Після кількох годин самозневажання та налагодження з допомогою console.log
, я переписав логіку. Виявилося, що замість Math.floor
потрібно було використовувати splice
.
Ми пізніше побачимо, чому не слід було використовувати Math.floor
, але поки що це працює чудово.
const clr = document.querySelector("#x");
clr.addEventListener("click", () => {
if (box.value.length > 0) {
box.value = box.value.slice(0, -1);
console.log("Після видалення останньої цифри", box.value);
}
});
Кнопка "Рівно": Зустрічайте всемогутній eval
Коли кнопки працювали правильно, наступним кроком було обробляти обчислення, коли натискається кнопка "=". Ось код:
function calculate() {
box.value = eval(box.value);
}
Ура, це спрацювало! Я лягав спати, почувши себе справжнім JavaScript-магом.
Обробка помилок
Але зачекайте. Хороший програміст не просто йде, коли код працює. Потрібно перевіряти крайні випадки. А що, якщо ідіот (гмм, це я) введе 4+
і натисне "="? Бум. Нічого не відбувається. Тиша. Розчарування.
Ми не можемо залишити користувачів у такій ситуації. Їм потрібні підказки, навіть якщо вони такі ж недбалими, як я.
Вводимо обробку помилок.
Використовуючи простий блок try-catch
, я додав спосіб обробляти некоректні введення:
function calculate() {
try {
box.value = eval(box.value);
} catch (e) {
box.value = "Введіть коректно, чувак. Що!?";
console.log(e);
}
}
Тепер, якщо хтось введе нісенітницю типу 5/*
і натисне "=", вони побачать дружнє повідомлення замість вічної тиші.
Ах, ці радощі від налагодження! Отже, я впевнено вирушив до проблеми "видалення останньої цифри", думаючи, що вже все зрозумів.
Все було добре до цього моменту, але для очищення останньої цифри Math.floor
працював ідеально раніше, але що, якщо є оператори? Тоді все піде не за планом.
Детальне пояснення, чому замість Math.floor
був використаний splice
Коли я ввів 6+6=12+23
, як справжній геній програмування, я натиснув свою кнопку CLR, очікуючи, що маленьке 3
на кінці зникне. Але о ні! Що мене зустріло замість цього — математичний жах NaN.
Я витріщався на екран, ошелешений, як ніби сам калькулятор насміхався з мене.
Виявилось, що проблема не в моїй логіці — хоча ні, зачекайте, то була саме моя логіка. Суть була в тому, що мій геніальний Math.floor(box.value / 10)
намагався виконати математичні операції зі рядком типу "12+23"
. Гарна новина: JavaScript не любить ділити рядки на числа. Результат? NaN.
Мій процес налагодження (або момент “Ага!”):
- Спочатку я п'ять хвилин дивився на екран, відмовляючись вірити.
- Потім я спробував додати кілька
console.log
як чарівний пил:console.log("remove", remove); console.log(box.value);
- І ось! Я зрозумів, що щоразу, коли я натискав
CLR
, математична операція намагалася зрозуміти"12+23" / 10
. ВЕЛИКЕ НІ.
Зрештою, мій мозок прошепотів: "Використовуй slice, дурню."
Виправлення:
Завдяки магії маніпулювання рядками, я замінив математичну операцію на магію slice
:
const clr = document.querySelector("#x");
clr.addEventListener("click", () =\> {
if (box.value.length > 0) {
box.value = box.value.slice(0, -1);
}
});
Наслідки:
Я знову ввів 6+6=12+23
. Натиснув CLR. 3
зникла. Натиснув знову. 2
зникла. Життя стало гарним. Мій калькулятор нарешті став нормальним інструментом, а не генератором образ.
Уроки, які я засвоїв: Американські гірки радості та розчарування
Створення цього калькулятора було поєднанням моментів “Ага!” і “О, чому ти мене ненавидиш?”. Але ось мої найбільші висновки:
- Фронтенд-дизайн: Зрозумій основи CSS перед тим, як починати. Не витрачай годину через
flex-direction
. - Прослуховувачі подій (Event Listeners): Не вкладати їх там, де вони не потрібні. Функції повинні бути чистими та логічними.
Простота - ключ: Іноді найкраще рішення - це найпростіше (привіт,slice()
). - Обробка помилок: Ніколи не припускайте, що користувачі будуть робити все правильно.
А в кінці, не забувайте сміятися з себе, коли все йде не за планом. Адже в кінці дня, ви навчаєтесь — і це найголовніше.
Тепер вибачте, я йду будувати гру хрестики-нулики з новоздобутою мудрістю.
Перекладено з: Ups and Downs of Making a Calculator in JavaScript