Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675

    [pillola snippet] Calcolatrice virtuale HTM/CSS/JS

    A seguito della discussione: http://forum.html.it/forum/showthrea...readid=2967663

    ho provato a rielaborare l'applicazione realizzata dall'utente lanvoel, cioè una calcolatrice virtuale in JavaScript. Ho cercato di impostare lo sviluppo secondo quelli che potrebbero essere i criteri per una buona programmazione. Ovviamente non è, e non vuole essere, un'applicazione di livello professionale, ma può essere invece una base implementabile e personalizzabile o uno snippet da cui prendere spunto o tuttalpiù un esercizio a scopo didattico.

    Ho impostato l'elaborato cercando di mantenere ben definite, come da buona norma, le tre componenti: HTML (struttura), CSS (presentazione), JavaScript (azione).
    Sarà quindi possibile esaminare/modificare/implementare distintamente ciascuno di questi aspetti.

    Propongo di seguito due versione, una prima versione più semplice (forse più digeribile da chi è a digiuno) e una più elaborata (sia nella parte CSS sia nel JavaScript).

    Nella versione semplice ho giusto "iniettato" le funzioni JavaScript attraverso l'evento onclick sui tag <input> che compongono i tasti della calcolatrice.

    E' chiaro che essendo una base, ci sono diverse carenze sopratutto a livello JavaScript. Una tra tutte è l'uso di eval() per l'elaborazione delle espressioni nel display. Dal momento che manca un controllo nell'inserimento dei dati, questa funzione può generare dei risultati inattesi se non altamente disastrosi. Infatti tale funzione va ad elaborare l'espressione risolvendola ed eseguendola come un normale script, per cui se non c'è un controllo accurato dei dati che gli si danno in pasto, è possibile che lo stesso risultato vada a rompere l'esecuzione dello script sulla pagina (per tale motivo spesso viene usata l'espressione "eval is evil").

    Ma ripeto, in questo caso parliamo di applicazione a scopo didattico, per cui non c'è da allarmarsi; anzi, chi volesse, potrà cimentarsi nell'implementare un sistema di validazione e controllo dei dati in input o, magari, proprio un sistema più robusto per l'inserimento dei dati, partendo appunto da questa base.

    Attualmente lo script che si occupa di questo sta dentro la funzione risolviEspressioneDisplay().

    Qui lo snippet della versione semplice (ci sono un po' di commenti ma nulla di troppo dettagliato, il codice mi pare già abbastanza autodescrittivo):
    codice:
    <!doctype html>
    <html lang="it">
       <head>
          <title>Calcolatrice</title>
          <style>                                                                          /*-- QUI IL CSS PER LA FORMATTAZIONE DI TUTTO IL LAYOUT --*/
                                                                                           
    
             * {
                box-sizing: border-box;                                                    /* Piccolo reset di base */
             }
             
             body {
                background: #e4dddb;
             }
             
             #calcolatrice {                                                               /* Contenitore principale */
                width: 350px;
                padding: 7px;
                background: #445066;
             }
             
             #display {                                                                    /* Display */
                width: 100%;
                margin: 5px 0 10px;
                padding: 4px;
                font: 24px/1 "Lucida Console", Monaco, monospace;
                text-align: right;
                border: 1px solid #112e13;
                color: #010d00;
                background: #a5cb8d;
             }
             
             #display::-ms-clear {                                                         /* Fix IE/Edge rimuove il noioso pulsante X che appare al focus dell'input */
                display: none;
             }
             
             #pulsantiera {                                                                /* Contenitore dei tasti */
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                justify-content: space-around;
                padding: 10px;
                background: #e0e1e9;
             }
             
             #pulsantiera input {                                                          /* Tasti */
                width: calc(90% / 4);                                                      /* Larghezza del tasto. Si crea una griglia a 4 colonne con un po' di spazio tra i tasti */
                margin: 3px 0;                                                             /* Interspazio tra le righe di tasti */
                padding: 5px;
                font: bold 20px/1.2 "Arial Black", Gadget, sans-serif;
                text-align: center;
                border: 1px solid #555;
                color: #fff;
                background: #7da5d6;
                cursor: pointer;
             }
             
             #pulsantiera input:hover {                                                    /* Hover sui tasti */
                border-color: #fff;
                opacity: .7;
             }
             
          </style>
          <script>                                                                         /*-- QUI IL JAVASCRIPT CON LE FUNZIONI PRINCIPALI --*/
             
             var display;
             
             window.onload = inizializza;
             
             function inizializza(){
                display = calcolatrice.display;                                            // Fix IE11, nel riferimento agli elementi del form deve essere specificato il nome del form
                                                                                           // (per gli altri browser funziona anche senza)
             }
             
             function aggiungiAlDisplay(valore){
                visualizza(display.value + valore);
             }
             
             function rimuoviUltimoCarattere(){
                visualizza(display.value.slice(0, -1));
             }
             
             function inserisciFunzione(nomeFunzione){
                visualizza(' '+nomeFunzione+'('+display.value+')');
             }
             
             function risolviEspressioneDisplay(){
                visualizza(eval(display.value));
             }
             
             function visualizza(valore){
                display.value = valore;
                spostaCursoreAllaFine(display);
             }
             
             function spostaCursoreAllaFine(el){                                           // Posiziono il cursore alla fine del campo e forzo la visualizzazione di quella parte quando il testo è più lungo del campo
                display.focus();
                el.style.textIndent = "-999em";                                            // Soluzione crossbrowser FF59, CH67, Edge, IE11
                el.onkeydown = function() {
                  this.style.textIndent = "0";
                  this.onkeydown = function(){};
                }
             }
             
          </script>
       </head>
       <body>                                                                              <!-- QUI IL CODICE HTML PER LA STRUTTURA DELL'APPLICAZIONE -->
                                                                                           <!-- Le funzioni JavaScript sono comunque richiamate attraverso l'evento onclick per ciascun tasto/input -->
          
          <form name="calcolatrice" id="calcolatrice" onsubmit="risolviEspressioneDisplay(); return false;">
          
             <input name="display" id="display" autofocus>
             <div id="pulsantiera">
                
                <input type="button" value="sin" onclick="inserisciFunzione('Math.sin')">
                <input type="button" value="cos" onclick="inserisciFunzione('Math.cos')">
                <input type="button" value="tan" onclick="inserisciFunzione('Math.tan')">
                <input type="button" value="atn" onclick="inserisciFunzione('Math.atan')">
                
                <input type="button" value="(" onclick="aggiungiAlDisplay('(')">
                <input type="button" value=")" onclick="aggiungiAlDisplay(')')">
                <input type="button" value="←" onclick="rimuoviUltimoCarattere()">
                <input type="reset"  value="C">
    
                <input type="button" value="1" onclick="aggiungiAlDisplay('1')">
                <input type="button" value="2" onclick="aggiungiAlDisplay('2')">
                <input type="button" value="3" onclick="aggiungiAlDisplay('3')">
                <input type="button" value="+" onclick="aggiungiAlDisplay('+')">
    
                <input type="button" value="4" onclick="aggiungiAlDisplay('4')">
                <input type="button" value="5" onclick="aggiungiAlDisplay('5')">
                <input type="button" value="6" onclick="aggiungiAlDisplay('6')">
                <input type="button" value="-" onclick="aggiungiAlDisplay('-')">
    
                <input type="button" value="7" onclick="aggiungiAlDisplay('7')">
                <input type="button" value="8" onclick="aggiungiAlDisplay('8')">
                <input type="button" value="9" onclick="aggiungiAlDisplay('9')">
                <input type="button" value="×" onclick="aggiungiAlDisplay('*')">
    
                <input type="button" value="0" onclick="aggiungiAlDisplay('0')">
                <input type="button" value="." onclick="aggiungiAlDisplay('.')">
                <input type="submit" value="=">
                <input type="button" value="÷" onclick="aggiungiAlDisplay('/')">
    
             </div>
             
          </form>
       </body>
    </html>
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  2. #2
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    Nella versione più "pompata" ho curato meglio l'aspetto sia grafico che funzionale. Per i tag tasti ho applicato diverse classi utili sia per la formattazione col CSS sia per attribuire via script le varie funzioni, questa volta senza passare per l'attributo onclick (così è invece nella versione semplice). Tutte le "azioni" sono quindi definite nel resto dello script in <head>.

    Il display è più grande. Nella versione semplice ho usato un input con singola riga mentre qui ha usato una textarea con un'altezza impostata da CSS che attualmente mostra 3 righe, ma ovviamente può essere personalizzata facilmente attraverso il CSS, come tutto il resto.

    In questa versione alcuni operatori e funzioni non vengono inseriti e mostrati con una sintassi JavaScript; ad esempio il "*" per la moltiplicazione viene mostrato come "×", così il "/" per la divisione viene mostrato come "÷", e ancora le funzioni "sin", "cos", ecc. sono inserite e mostrate esattamente con quelle relative diciture anziché "Math.sin", "Math.cos", ecc.
    Questo per migliorare l'aspetto nella rappresentazione sul display, nonché ottimizzare gli spazi.

    Nella funzione risolviEspressioneDisplay() viene poi richiamata la funzione sostituisciValoriSpeciali() che si occupa appunto di "convertire" l'espressione, rimpiazzando quei valori speciali con i relativi valori JavaScript, in modo da renderla appetibile dal famoso eval().

    Ovviamente anche in questo caso il tutto può essere "facilmente" implementato/migliorato.

    Qui lo snippet:
    codice:
    <!doctype html>
    <html lang="it">
       <head>
          <title>Calcolatrice</title>
          
          <style>
             /*-- Qui il CSS per la formattazione di tutto il layout --*/
             
             * {
                box-sizing: border-box;
             }
             
             body {
                background: #e4dddb;
             }
             
             #calcolatrice {
                width: 350px;
                padding: 7px;
                border-radius: 6px;
                background: #445066;
                box-shadow: 2px 2px 4px rgba(0,0,0,.5);
             }
             
             #display {
                width: 100%;
                height: 3.5em;
                resize: none;
                margin: 5px 0 10px;
                padding: 4px 4px 2px;
                font: 24px/1 "Lucida Console", Monaco, monospace;
                text-align: right;
                border: 1px solid #112e13;
                border-radius: 4px;
                color: #010d00;
                background: #a5cb8d;
                overflow-y: auto;
             }
             
             #display::-moz-selection {
                color: #062;
                background: #9bff9b;
             }
             #display::selection {
                color: #062;
                background: #9bff9b;
             }
             
             #pulsantiera {
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                justify-content: space-around;
                padding: 10px;
                border-radius: 3px;
                background: #e0e1e9;
             }
             
             #pulsantiera input {
                width: calc(90% / 4);
                margin: 3px 0;
                padding: 5px;
                font: bold 20px/1.2 "Arial Black", Gadget, sans-serif;
                text-align: center;
                border: 1px solid #555;
                border-radius: 4px;
                cursor: pointer;
                box-shadow: inset 0 0 20px rgba(0,0,0,0);
                transition: .3s;
             }
             
             #pulsantiera input:hover {
                border-color: #fff;
                box-shadow: inset 0 -40px 5px rgba(0,0,0,.15);
                transition: .1s;
             }
             
             /* - Colori tasti - */
             
             #pulsantiera input         { background: #7da5d6; color: #fff;    }
             #pulsantiera .resetta      { background: #db3b3b;                 }
             #pulsantiera .rimuovi      { background: #c7c8c2; color: #cc2e38; }
             
             #pulsantiera .operatore    ,
             #pulsantiera .separatore   ,
             #pulsantiera .parentesi    { background: #c7c8c2;                 }
             
             #pulsantiera .risolvi      { background: #21b476;                 }
             #pulsantiera .funzione     { background: #cc6c4b;                 }
             
             
          </style>
          <script>
             /*-- Qui il JavaScript per tutte le azioni dell'applicazione --*/
             
             var display;
             
             window.onload = inizializza;
             
             function inizializza(){
                display = calcolatrice.display; //Fix IE11
                
                calcolatrice.onsubmit = function(e){e.preventDefault();}
                
                display.focus();
                
                display.onkeydown = function(e){
                   if(e.keyCode == 13){ // Se premo invio nel display, vado a risolvere
                      risolviEspressioneDisplay();
                      e.preventDefault();
                   }
                }
                
                var tasti = document.querySelectorAll('#pulsantiera>input');
                var i = tasti.length;
                while(i--){
                   tasto = tasti[i]
                   classe = tasto.classList;
                   
                        if (classe.contains('funzione'))  tasto.onclick = function(){inserisciFunzione(this.value);};
                   else if (classe.contains('risolvi'))   tasto.onclick = risolviEspressioneDisplay;
                   else if (classe.contains('rimuovi'))   tasto.onclick = rimuoviUltimoCarattere;               
                   else                                   tasto.onclick = function(){aggiungiAlDisplay(this.value);};
                   
    
                };
             }
             
             function aggiungiAlDisplay(valore){
                visualizza(display.value + valore);
             }
             
             function rimuoviUltimoCarattere(){
                visualizza(display.value.slice(0, -1));
             }
             
             function inserisciFunzione(nomeFunzione){
                visualizza(' '+nomeFunzione+'('+display.value+')');
             }
             
             function risolviEspressioneDisplay(){
                var espressione = sostituisciValoriSpeciali(display.value);
                visualizza(eval(espressione));
             }
             
             function sostituisciValoriSpeciali(espressione) {
                var coppieValori = [
                    ['sin', 'Math.sin'  ]
                   ,['cos', 'Math.cos'  ]
                   ,['tan', 'Math.tan'  ]
                   ,['atn', 'Math.atan' ]
                   ,['×'  , '*'         ]
                   ,['÷'  , '/'         ]
                ]
                for (var i = 0; i < coppieValori.length; i++)
                   espressione = espressione.replace(new RegExp(coppieValori[i][0],"g"), coppieValori[i][1]);
                return espressione;
             };
             
             function visualizza(valore){
                display.value = valore;
                spostaCursoreAllaFine(display);
             }
             
             function spostaCursoreAllaFine(el){ // Posiziono il cursore e lo scroll alla fine della textaea
                el.focus();
                el.scrollTop = el.scrollHeight
             }
             
          </script>
       </head>
       <body>
          <!-- Qui il codice HTML per la struttura dell'applicazione -->
          <form name="calcolatrice" id="calcolatrice">
          
             <textarea name="display" id="display"></textarea>
             <div id="pulsantiera">
                
                <input type="button" value="sin" class="funzione sin">
                <input type="button" value="cos" class="funzione cos">
                <input type="button" value="tan" class="funzione tan">
                <input type="button" value="atn" class="funzione atn">
                
                <input type="button" value="(" class="parentesi">
                <input type="button" value=")" class="parentesi">
                <input type="button" value="←" class="rimuovi" >
                <input type="reset"  value="C" class="resetta">
    
                <input type="button" value="1">
                <input type="button" value="2">
                <input type="button" value="3">
                <input type="button" value="+" class="operatore addizione">
    
                <input type="button" value="4">
                <input type="button" value="5">
                <input type="button" value="6">
                <input type="button" value="-" class="operatore sottrazione">
    
                <input type="button" value="7">
                <input type="button" value="8">
                <input type="button" value="9">
                <input type="button" value="×" class="operatore moltiplicazione">
    
                <input type="button" value="0">
                <input type="button" value="." class="separatore">
                <input type="submit" value="=" class="risolvi">
                <input type="button" value="÷" class="operatore divisione">
    
             </div>
             
          </form>
       </body>
    </html>

    Buono sviluppo.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    PS: se, provando il codice, vedete strani caratteri nei tasti, provate a risalvare il file dal vostro editor impostando una codifica UTF-8
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    Faccio presente che i codici riportati sono soggetti ad aggiornamenti/migliorie.
    Ho già apportato qualche modifica ma per non inquinare questa discussione aggiornerò direttamente i Pen; si faccia eventualmente riferimento a quei codici.

    changelog:
    - Sostituito il tag <form> con un più generico e semplice <div>
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Amministratore L'avatar di Vincent.Zeno
    Registrato dal
    May 2003
    residenza
    Emilia-Romagna (tortellini und cappelletti land!)
    Messaggi
    20,649
    un po' di esercizio per tenerti in allenamento?

    il tasto C non dovrebbe cancellare?

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    un po' di esercizio per tenerti in allenamento?
    già, devo tenermi la testa in caldo

    il tasto C non dovrebbe cancellare?
    oops si è rotto dopo l'aggiornamento.. ho fixato ora. Thx
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  8. #8
    La divisione per zero non dovrebbe essere consentita... ...però non è che stiamo qua a guardare... ...il capello...

  9. #9
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,675
    La divisione per zero non dovrebbe essere consentita...
    Beh dai, il suo messaggio "Infinity" lo mostra. In effetti sono tutte le altre cose non consentite che dovrebbero essere vietate
    In teoria, come accennavo nel primo post, si potrebbero aggiungere i dovuti controlli nella funzione risolviEspressioneDisplay() prima che sia restituito il risultato. Magari in qualche prossima release.

    ...però non è che stiamo qua a guardare... ...il capello...

    lo spaccherei in 4 se ancora ne avessi in testa

    ... però potrei tentare di dividerlo per 0
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  10. #10
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,505
    veramente un bel lavoro
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.