Tutorial para Crear una Calculadora Científica con JavaScript y HTML5
En este tutorial aprenderás a construir una calculadora científica desde cero utilizando JavaScript, HTML5 y CSS3. Está diseñado para desarrolladores principiantes e intermedios interesados en fortalecer su comprensión de la programación frontend y el desarrollo web con JavaScript. Veremos cómo crear una interfaz amigable, implementar operaciones básicas y funciones avanzadas, manejar eventos y validar entradas para una experiencia robusta y fluida.
Índice
- Diseñando la interfaz de usuario con HTML5 y CSS3
- Implementando la lógica matemática en JavaScript
- Manejo de eventos y validación de entradas
- Conclusión y buenas prácticas
Diseñando la interfaz de usuario con HTML5 y CSS3
Comenzaremos creando la estructura básica de la calculadora y estilizando sus componentes para un diseño limpio y funcional.
Estructura HTML
Creamos un archivo index.html
con los elementos esenciales:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Calculadora Científica - Tutorial</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <main class="calculator"> <input type="text" class="display" id="display" disabled /> <section class="buttons"> <!-- Operadores científicos --> <button data-action="sin">sin</button> <button data-action="cos">cos</button> <button data-action="tan">tan</button> <button data-action="log">log</button> <!-- Operadores básicos --> <button data-action="clear">C</button> <button data-action="backspace">←</button> <button data-action="(">(</button> <button data-action=")">)</button> <!-- Números y operadores --> <button>7</button> <button>8</button> <button>9</button> <button data-action="/">÷</button> <button>4</button> <button>5</button> <button>6</button> <button data-action="*">×</button> <button>1</button> <button>2</button> <button>3</button> <button data-action="-">−</button> <button>0</button> <button>.</button> <button data-action="^">^</button> <button data-action="+">+</button> <button data-action="ans">Ans</button> <button data-action="equal" class="equal">=</button> </section> </main> <script src="script.js"></script> </body> </html> |
Explicación:
- El
<input>
con clasedisplay
funciona para mostrar la expresión y el resultado. - Los botones tienen atributos
data-action
para identificar acciones específicas, diferenciando números de operadores y funciones. - Se incluyen características científicas básicas: seno, coseno, tangente y logaritmo.
Estilos CSS
Creamos un archivo styles.css
para que la calculadora sea atractiva y usable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
body { font-family: Arial, sans-serif; background: #282c34; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .calculator { background: #3b3f47; border-radius: 10px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); width: 320px; padding: 20px; } .display { width: 100%; height: 50px; font-size: 1.5rem; text-align: right; padding: 10px; margin-bottom: 15px; border-radius: 5px; border: none; background: #222; color: #fff; } .buttons { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 10px; } button { padding: 15px 0; font-size: 1.2rem; border: none; border-radius: 5px; background: #4d5159; color: #fff; cursor: pointer; transition: background 0.3s; } button:hover { background: #60656e; } button.equal { grid-column: span 2; background: #ff9500; color: #fff; font-weight: bold; } button.equal:hover { background: #e08900; } |
Explicación:
- Usamos
grid
para distribuir botones uniformemente. - El botón
=
ocupa dos columnas para destacarlo. - El color oscuro brinda un look moderno y cómodo para la vista.
Implementando la lógica matemática en JavaScript
En script.js
implementamos la lógica para interpretar y ejecutar las operaciones que el usuario seleccione.
Variables y referencias iniciales
1 2 3 4 5 6 7 |
// Referencias a elementos DOM const display = document.getElementById('display'); const buttons = document.querySelectorAll('button'); let expression = ''; // expresión actual mostrada let lastAnswer = ''; |
Función para sanitizar y evaluar expresiones
Para interpretar expresiones, usaremos la función eval
con precaución. Además, implementaremos conversión de funciones científicas a JavaScript.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/** * Evalúa la expresión científica ingresada y devuelve resultado o error. * Reemplaza funciones científicas por llamadas de Math correspondientes. * @param {string} expr - Expresión ingresada * @returns {string} Resultado formateado o mensaje de error */ function evaluateExpression(expr) { try { // Reemplazar funciones personalizadas a JavaScript let sanitized = expr .replace(/sin\(/g, 'Math.sin(toRadians(') .replace(/cos\(/g, 'Math.cos(toRadians(') .replace(/tan\(/g, 'Math.tan(toRadians(') .replace(/log\(/g, 'Math.log10(') .replace(/\^/g, '**') // operador potencia .replace(/Ans/g, lastAnswer || '0'); // evaluar la expresión let result = eval(sanitized); // Limitar resultado decimal if(typeof result === 'number') { result = Math.round((result + Number.EPSILON) * 1e10) / 1e10; } return result.toString(); } catch (e) { return 'Error'; } } // Ayuda para convertir grados a radianes (Math usa radianes) function toRadians(deg) { return deg * (Math.PI / 180); } |
Explicación:
- Las funciones trigonométricas en calculadoras científicas suelen usar grados, JavaScript usa radianes; por ello creamos la función
toRadians
. log
se interpreta como logaritmo base 10 conMath.log10
.- El operador
^
se convierte en**
para potencia. - La variable
Ans
permite reutilizar el último resultado. eval
se usa para realizar el cálculo con la expresión modificada.
Manejo de botones y eventos
Capturaremos clics en los botones y actualizaremos la expresión en pantalla.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
buttons.forEach(button => { button.addEventListener('click', () => { const action = button.getAttribute('data-action'); const value = button.textContent; switch (action) { case 'clear': expression = ''; display.value = ''; break; case 'backspace': expression = expression.slice(0, -1); display.value = expression; break; case 'equal': const result = evaluateExpression(expression); display.value = result; if (result !== 'Error') { lastAnswer = result; expression = result; } else { expression = ''; } break; case 'sin': case 'cos': case 'tan': case 'log': expression += `${action}(`; display.value = expression; break; case '^': case '+': case '-': case '*': case '/': case '(': case ')': expression += action; display.value = expression; break; case 'ans': expression += lastAnswer; display.value = expression; break; default: // Número o punto expression += value; display.value = expression; break; } }); }); |
Explicación:
- Usamos
data-action
para identificar y ejecutar operaciones especiales. - Los botones numéricos y el punto concatenan caracteres a la expresión.
- Al presionar
=
, evaluamos la expresión y actualizamos la pantalla y memoria. clear
limpia todo, ybackspace
borra el último carácter.- Funciones como
sin(
añaden paréntesis automáticamente.
Validación básica de entradas
Para evitar errores comunes, agregamos un control simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Función simple para validar antes de calcular function isValidExpression(expr) { // No puede iniciar con operador excepto paréntesis o signo menos if (/^[+*/^]/.test(expr)) return false; // Paréntesis balanceados let stack = []; for (let char of expr) { if (char === '(') stack.push(char); else if (char === ')') { if (stack.length === 0) return false; stack.pop(); } } if (stack.length !== 0) return false; // No caracteres inválidos if (/[^0-9.+\-*/^()a-zA-Z]/.test(expr)) return false; return true; } // Uso en evaluación: if (isValidExpression(expression)) { const result = evaluateExpression(expression); // ... } else { display.value = 'Expresión inválida'; expression = ''; } |
Explicación:
- La función verifica que los paréntesis estén balanceados.
- Prohíbe expresiones que comienzan con operadores incorrectos.
- Rechaza caracteres extraños que pueden causar fallos.
La validación puede ampliarse, pero este enfoque es un buen punto de partida.
Manejo de eventos y validación de entradas
Además de validar la expresión antes de la evaluación, podemos mejorar la experiencia del usuario manejando el teclado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// Permitir la entrada por teclado document.addEventListener('keydown', (event) => { const allowedKeys = '0123456789+-*/().^'; const key = event.key; if (allowedKeys.includes(key)) { expression += key; display.value = expression; } else if (key === 'Enter') { if (isValidExpression(expression)) { const result = evaluateExpression(expression); display.value = result; if (result !== 'Error') { lastAnswer = result; expression = result; } else { expression = ''; } } else { display.value = 'Expresión inválida'; expression = ''; } event.preventDefault(); } else if (key === 'Backspace') { expression = expression.slice(0, -1); display.value = expression; event.preventDefault(); } else if(key === 'Escape'){ expression = ''; display.value = ''; event.preventDefault(); } }); |
Explicación:
- Permitimos que el usuario escriba la expresión directamente usando teclado.
- Enter ejecuta la evaluación.
- Backspace permite borrar el último carácter.
- Escape limpia la pantalla.
Conclusión y buenas prácticas
¡Felicidades por haber creado tu propia calculadora científica usando JavaScript y HTML5! Este proyecto cubre aspectos clave del desarrollo web con JavaScript y promueve buenas prácticas en programación frontend.
Resumen de lo aprendido
- Construcción de una interfaz de usuario clara y funcional con HTML5 y CSS3.
- Implementación de la lógica matemática con funciones de JavaScript, cuidando detalles como grados/radianes y funciones científicas.
- Manejo robusto de eventos para interactuar con botones y teclado.
- Validación básica de expresiones para evitar errores comunes.
- Modularización y comentarios para facilitar la lectura y mantenimiento.
Buenas prácticas recomendadas
- Evita usar
eval
en entornos reales, debido a problemas de seguridad. Para producción, considera librerías como math.js. - Separa la lógica de negocio y la interfaz para un código más limpio y manejable.
- Incluye pruebas unitarias cuando el proyecto crezca.
- Maneja errores de usuario con mensajes claros para mejorar la UX.
- Añade accesibilidad para usuarios con diferentes necesidades.
Te animamos a ampliar la calculadora con nuevas funciones (factoriales, funciones hiperbólicas), añadir historial de operaciones, o incluso convertirla en una app móvil con frameworks frontend.
¡Da el siguiente paso en tu carrera como desarrollador frontend!
¿Te gustó este tutorial? Comparte tu experiencia y sigue explorando más sobre tutorial calculadora JavaScript, calculadora científica HTML5, y otras temáticas de programación frontend.