Semplice calcolatrice
Qui trovate tutti i codici utilizzati per la calcolatrice. Sono tutti ampiamente spiegati e commentati. Fate attenzione perchè i collegamenti ai file dipendono da dove sono collocati; Struttura che ho utilizzato io:
- calcolatrice
- bower_components
- css
- img
- index.html
- main.js
index.html
<!DOCTYPE html>
<html>
<!--
====================================================================
LAYOUT DELL CALCOLATRICE
====================================================================
Calcolatrice utilizza un layout di tipo flex annidato.
1. div.calcolatrice:
Layout flex di tipo column dall'alto verso il basso. La
disposizione del contenuto è determinata dalla proprietà
justify-content: space-between. Contiene tre elementi:
header.top-bar, div.carta e div.tastiera
2. header.top-bar
Layout flex di tipo row orizzontale. La disposizione
del contenuto è determinata dalla proprietà
justify-content: space-between. Sono presenti due elementi:
img.logo e span.title.
3. div.carta
Layout flex di tipo column dall'alto verso il basso.
Contiene un solo elemento: div#userInput
4. div.tastiera
Layout flex di tipo column dall'alto verso il basso. Contiene
5 elementi div.riga ognino dei quali occupa il 20% dello spazio
(flex: 0 0 20%).
5. div.riga
Layout flex di tipo row orizzontale. Ogni riga contiene elementi
div.colonna-1, div.colonna-2 o div.colonna-3 rispettivamente
larghi 25%, 50% e 75% dello spazio a disposizione.
6. div.colonna-1, div.colonna-2, div.colonna-3
Elementi uguali son non per la larghezza (flex: 0 0 25%,
flex: 0 0 50%, flex: 0 0 75%) sono i contenitori dei tasti
(button.tasto). Il margine superiore e inferiore è dato
dal padding (margine interno) dell'elemento row che li contiene
7. button.tasto
button.tasto è alto e largo quanto l'elemento div.colonna che
lo contiene. Il margine tra un bottone e l'altro è dato dal
padding (margine interno) della div che contiene il bottone.
Quando necessario al button.tasto viene aggiunta l'attributo
data-val che contiene il valore da utilizzare nell'espressione
da valutare con javascript al posto del valore del button stesso.
Ad esempio il taso "," ha data-val="." che è il separatore dei
decimali utilizzato in javascript.
-->
<head>
<title>Calcolatrice</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="bower_components/base.reset/reset.css" />
<link rel="stylesheet" href="css/stile.css" />
</head>
<body>
<div class="calcolatrice">
<!-- Testata -->
<header class="top-bar">
<img class="logo" src="img/Logo-Accademia.png" />
<span class="title">Calcolatrice</span>
</header>
<!-- CARTA -->
<div class="carta">
<div id="userInput" class="immissione">0</div>
</div>
<!-- Tastiera calcolatrice-->
<div class="tastiera">
<!-- RIGA -->
<div class="riga">
<!-- COLONNE -->
<div class="colonna-1">
<button type="button" class="tasto">C</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">(</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">)</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">+</button>
</div>
</div>
<!-- RIGA -->
<div class="riga">
<!-- COLONNE -->
<div class="colonna-1">
<button type="button" class="tasto">1</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">2</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">3</button>
</div>
<div class="colonna-1">
<button type="button" data-val="-" class="tasto">−</button>
</div>
</div>
<!-- RIGA -->
<div class="riga">
<!-- COLONNE -->
<div class="colonna-1">
<button type="button" class="tasto">4</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">5</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">6</button>
</div>
<div class="colonna-1">
<button type="button" data-val="*" class="tasto">×</button>
</div>
</div>
<!-- RIGA -->
<div class="riga">
<!-- COLONNE -->
<div class="colonna-1">
<button type="button" class="tasto">7</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">8</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">9</button>
</div>
<div class="colonna-1">
<button type="button" data-val="/" class="tasto">÷</button>
</div>
</div>
<!-- RIGA -->
<div class="riga">
<!-- COLONNE -->
<div class="colonna-2">
<button type="button" class="tasto">0</button>
</div>
<div class="colonna-1">
<button type="button" data-val="." class="tasto">,</button>
</div>
<div class="colonna-1">
<button type="button" class="tasto">=</button>
</div>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
css/stile.css
Stili utilizzati nella calcolatrice. Ho incluso anche il foglio di stile bower_components/base.reset/reset.css
che le impostazione base che uniformano i browser senza creare alcuna classe.
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-size: 16px;
font-weight: 300;
}
/*==================================================
Contenitore della calcolatrice
==================================================*/
.calcolatrice {
height: 100vh;
background-color: #666666;
color: white;
/* margine attorno alla calcolatrice */
padding: 15px;
/* Layout flex */
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
/* disposizione degli elementi contenuti */
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
/*==================================================
Carta
==================================================*/
.carta {
background-color: #eeeeee;
color: #333333;
/* Layout flex */
-webkit-box-flex: 1;
-ms-flex: 1 1 1%;
flex: 1 1 1%;
}
/*==================================================
Elemento che mostra l'espressione che l'utente
sta componendo e, quando l'utente preme '=' il
risultato
==================================================*/
.carta .immissione {
font-size: 3em;
text-align: right;
}
/*==================================================
Testata con logo e titolo
==================================================*/
.top-bar {
max-height: 2.7em;
width: 100%;
padding-bottom: 5px;
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, ha un'altezza di 2.7em */
-webkit-box-flex: 0;
-ms-flex: 0 0 2.7em;
flex: 0 0 2.7em;
/* Impostazioni come CONTENITORE flex: flusso
orizzontale, contenuto disposto come
justify-content: space-between */
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
/*==================================================
Logo barra superiore
==================================================*/
.top-bar .logo {
max-height: 100%;
width: auto;
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, larghezza minima possibile*/
-webkit-box-flex: 0;
-ms-flex: 0 0 1%;
flex: 0 0 1%;
}
/*==================================================
Titolo barra superiore
==================================================*/
.top-bar .title {
font-size: 1.2em;
font-weight: 700;
}
/*==================================================
TASTIERA
==================================================*/
.tastiera {
max-height: 70%;
padding-top: 2px;
/* Impostazioni come CONTENUTO flex: non cresce,
può calare, ha un'altezza di base del 70% */
-webkit-box-flex: 0;
-ms-flex: 0 1 70%;
flex: 0 1 70%;
/* Impostazioni come CONTENITORE flex con flusso
verticale */
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
}
/*==================================================
RIGA DI TASTI NELLA TASTIERA
==================================================*/
.riga {
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, ha un'altezza del 20% */
-webkit-box-flex: 0;
-ms-flex: 0 0 20%;
flex: 0 0 20%;
/* Impostazioni come CONTENITORE flex con flusso
orizzontale */
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
/* I due margini esterni negativi servono a compensare
il padding degli elementi .colonna- contenuti
garantendo un corretto allineamento esterno dei
tasti*/
margin-left: -2px;
margin-right: -2px;
}
/*======================================================
COLONNE
Tre elementi identici in cui cambia solo la larghezza
=====================================================*/
.colonna-1 {
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, ha una larghezza del 25% */
-webkit-box-flex: 0;
-ms-flex: 0 0 25%;
flex: 0 0 25%;
max-width: 25%;
/* Margine interno che garantisce la distanza tra
i tasti */
padding: 2px;
}
.colonna-2 {
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, ha una larghezza del 50% */
-webkit-box-flex: 0;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
/* Margine interno che garantisce la distanza tra
i tasti */
padding: 2px;
}
.colonna-3 {
/* Impostazioni come CONTENUTO flex: non cresce,
non cala, ha una larghezza del 75% */
-webkit-box-flex:0;
-ms-flex:0 0 75%;
flex:0 0 75%;
max-width: 75%;
/* Margine interno che garantisce la distanza tra
i tasti */
padding: 2px;
}
/*==================================================
TSTO DELLA CALCOLATRICE
==================================================*/
.tasto {
/* Il tasto occupa l'intero spazio definito
dall'elemento .colonna- che lo contiene*/
width: 100%;
height: 100%;
color: #333;
background-color: #dddddd;
border: 0;
font-size: 1.5em;
}
/* Sugli schermi di larghezza superiore a tablet con
orientamento portrait la grandezza dei font dei
tasti viene postata a 2.5em */
@media screen and (min-width: 768px) {
.tasto {
font-size: 2.5em;
}
}
main.js
/*==================================================
CALCOLATRICE
Il codice è molto semplificato. Possibili
miglioramenti:
- Tenere traccia de calcoli effettuati in una
specie di history
- Comporre l'espressione 'visibile' utilizzando
i segni che l'utente si aspetta (':' e non '/'
per la divisione, ',' e non '.' come separatore
decimale, ecc.) e convertire l'espressione in
un espressione legale quando si effettua il
calcolo.
==================================================*/
// div che viene utilizzata per mostrare l'espressione
// che viene composta usando i tasti della calcolatrice
var immissione = document.getElementById('userInput');
// nodeList che contiene tutti gli elemento con classe
//'tasto' cioè tutti i tasti della calcolatrice
var tasti = document.getElementsByClassName('tasto');
/* ==================================================
Con un ciclo 'for' scorro tutti gli elementi
contenuti nella nodeList tasti e a tutti
questi elementi (che sono tutti i tasti della mia
calcolatrice) aggiungo un gestore di eventi per
l'evento 'click'
==================================================*/
for(var i = 0; i < tasti.length; i++) {
var tasto = tasti[i];
/* -------- GESTORE DELL'EVENTO CLICK ---------
NOTA BENE: Nel gestore di evento la parola
riservata 'this' indica il tasto che riceve
l'evento 'click' che può essere provocato o
dal click del mouse (bottone sinistro per
i mouse impostato per i destri, destro per i
mouse impostato per i mancini) o dal tocco su
un dispositivo touch.
*/
tasto.addEventListener('click', function(){
// La variabile 'valore' contiene il carattere
// corrispondente al tasto premuto
var valore;
// 1. Determino il 'valore' del tasto
if (this.getAttribute('data-val') != null) {
// Se il button.tasto ha un attributo
// data-val a valore è assegnato il valore
// dell'attributo data-val
valore = this.getAttribute('data-val');
} else {
// Altrimenti a valore è assegnato
// il contenuto del button.tasto
valore = this.innerHTML;
}
// 2. A secondo di cosa contiene valore eseguo
// l'azione conseguente.
if (valore == "C") {
// Se è stato premuto il tasto 'C' cancello
// il contenuto di quanto immesso e lo
// sostituisco con '0'
immissione.innerHTML = "0";
} else if (valore == "=") {
// Se è stato premuto il tasto '=' prendo
// quanto immesso e calcolo il valore
// dell'espressione che ho composto utilizzando
// la funzione Javascript globale eval().
// Inserisco il risultato in div#userInput
var espressione = immissione.innerHTML;
immissione.innerHTML = eval(espressione);
} else {
// Negli altri casi prendo il valore del tasto
// premuto, lo aggiungo all'espressione da
// calcolare e visualizzo il risultato in
// div#userInput
var espressione = immissione.innerHTML;
if (espressione == '0') {
espressione = '';
}
espressione += valore;
immissione.innerHTML = espressione;
}
});
}