آموزش ساخت ماشین حساب با جاوااسکریپت
🎯 اهداف یادگیری
- آشنایی با اصول اولیه DOM Manipulation
- یادگیری مدیریت رویدادها در جاوااسکریپت
- پیاده سازی منطق عملیات ریاضی
- ساخت یک پروژه عملی و کاربردی
📌 ساختار HTML ماشین حساب
ابتدا ساختار پایه ماشین حساب را با HTML میسازیم:
html
<!-- ساختار اصلی ماشین حساب --><div class="calculator"> <input type="text" class="display" disabled> <div class="buttons"> <button class="btn" data-value="7">7</button> <button class="btn" data-value="8">8</button> <button class="btn" data-value="9">9</button> <button class="btn operator" data-value="+">+</button> <!-- سایر دکمهها --> </div></div>
توضیحات ساختار:
- ورودی نمایشگر: برای نمایش اعداد و نتایج
- دکمههای اعداد: با data-value برای مقداردهی
- دکمههای عملگرها: کلاس operator برای تشخیص عملگرها
📌 استایلدهی با CSS
برای زیباتر شدن ماشین حساب از CSS استفاده میکنیم:
css
.calculator { width: 300px; margin: 0 auto; border: 1px solid #ccc; border-radius: 5px; padding: 10px;}.display { width: 100%; height: 40px; margin-bottom: 10px; text-align: right;}.buttons { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;}
ویژگیهای CSS:
- طرحبندی شبکهای: استفاده از Grid برای چیدمان دکمهها
- طراحی واکنشگرا: مناسب برای تمام دستگاهها
- استایلدهی نمایشگر: تراز متن به راست و اندازه مناسب
📌 پیادهسازی منطق جاوااسکریپت
حالا به بخش اصلی پروژه یعنی پیادهسازی منطق ماشین حساب میرسیم:
javascript
// انتخاب المانهای مورد نیازconst display = document.querySelector('.display');const buttons = document.querySelectorAll('.btn');// متغیرهای محاسباتlet currentInput = '';let firstOperand = null;let operator = null;let waitingForSecondOperand = false;// افزودن رویداد کلیک به دکمههاbuttons.forEach(button => { button.addEventListener('click', (e) => { const value = e.target.getAttribute('data-value'); if (e.target.classList.contains('operator')) { handleOperator(value); return; } handleNumber(value); updateDisplay(); });});
توابع کمکی:
javascript
function handleNumber(number) { if (waitingForSecondOperand) { currentInput = number; waitingForSecondOperand = false; }else { currentInput = currentInput === '' ? number : currentInput + number; }}function handleOperator(nextOperator) { const inputValue = parseFloat(currentInput); if (operator && waitingForSecondOperand) { operator = nextOperator; return; } if (firstOperand === null) { firstOperand = inputValue; }else { const result = calculate(firstOperand, inputValue, operator); currentInput = String(result); firstOperand = result; } waitingForSecondOperand = true; operator = nextOperator;}
تابع محاسبات:
javascript
function calculate(firstOperand, secondOperand, operator) { switch (operator) { case '+': return firstOperand + secondOperand; case '-': return firstOperand - secondOperand; case '*': return firstOperand * secondOperand; case '/': return firstOperand / secondOperand; default: return secondOperand; }}function updateDisplay() { display.value = currentInput;}
ویژگیهای منطق ماشین حساب:
- مدیریت وضعیت: پیگیری عملوندها و عملگرها
- پشتیبانی از عملیات متوالی: امکان انجام چندین محاسبه پشت سر هم
- خطایابی: مدیریت موارد خاص مانند تقسیم بر صفر
📌 بهبود پروژه
برای حرفهایتر شدن پروژه، این ویژگیها را اضافه کنید:
javascript
// دکمه پاک کردن (C)function clearCalculator() { currentInput = ''; firstOperand = null; operator = null; waitingForSecondOperand = false; updateDisplay();}// دکمه اعشار (.)function inputDecimal(dot) { if (waitingForSecondOperand) { currentInput = '0.'; waitingForSecondOperand = false; return; } if (!currentInput.includes(dot)) { currentInput += dot; }}
ویژگیهای پیشرفته:
- پشتیبانی از اعداد اعشاری: استفاده از نقطه اعشار
- پاک کردن حافظه: قابلیت reset کردن ماشین حساب
- مدیریت خطاها: نمایش پیام برای عملیات نامعتبر
📌 تمرین عملی
این ویژگیها را به ماشین حساب اضافه کنید:
- دکمه درصد (%) برای محاسبه درصد
- دکمه تغییر علامت (±)
- پشتیبانی از صفحه کلید (اضافه کردن event listener برای کلیدها)
javascript
// راهنمای پیادهسازی پشتیبانی از صفحه کلیدdocument.addEventListener('keydown', (e) => { if (e.key >= '0' && e.key <= '9') { handleNumber(e.key); }else { switch (e.key) { case '+': case '-': case '*': case '/': handleOperator(e.key); break; case '.': inputDecimal(e.key); break; case 'Enter': handleOperator('='); break; } } updateDisplay();});