Ciao, risposta breve: converti i valori in tipo numerico aggiungendo un + davanti, in questo modo:
codice:
var inizio = +dati.start.value;
var fine = +dati.end.value;
- Risposta lunga:
Qualcuno più esperto sa dirmi dove
sbalio
Sicuramente nella "g" che hai dimenticato ... scherzo.
Sebbene il problema, in sé, sia facilmente risolvibile convertendo opportunamente i valori in gioco, la causa del problema non è altrettanto semplice da spiegare se non si approfondiscono alcuni punti.
Uno dei punti è relativo alla coercion ... in italiano coercizione; cioè nel typecasting implicito spe'... nella conversione automatica del tipo di dati effettuata dall'interprete JavaScript ... vabbè in questa roba scritta su wikipedia https://it.wikipedia.org/wiki/Conversione_di_tipo
Essendo JavaScript un linguaggio debolmente tipizzato, in mancanza di un'esplicita dichiarazione del tipo di dato, prima che avvenga qualsiasi confronto/operazione tra due dati, l'interprete controllerà se questi valori devono e possono essere convertiti; se è il caso, cercherà di eseguire una conversione consona del tipo di dato per i valori coinvolti, cioè in base al contesto e seguendo ovviamente dei criteri definiti dall'algoritmo di elaborazione.
Quando scrivi var inizio = dati.start.value; la variabile inizio è di tipo string perché il valore recuperato dall'attributo value di un elemento input è appunto una stringa testuale (a prescindere dal valore number che hai specificato per l'attributo type sul tag).
Cosa succede quindi?
Arrivati alla riga for(i=inizio; i <= fine; i++) stai adoperando questi due particolari operatori ("<=" e "++") in cui sono coinvolti dei valori che sono di tipo string... e non dovrebbero esserlo.
Ovviamente la prima espressione i=inizio attribuisce semplicemente alla variabile i il valore della variabile inizio (che è, appunto, un valore di tipo string).
L'operatore "<=" stabilisce quindi la condizione per cui il ciclo deve andare avanti.
Ora, cosa viene restituito da questa condizione?
Dal momento che non hai convertito quei valori in maniera esplicita, stai lasciando libertà di interpretazione ai criceti dietro il tuo browser. L'esecuzione di simili operazioni in molti casi restituisce dei risultati, tutto sommato, prevedibili; in alcune situazioni però si ottengono dei risultati del tutto inaspettati, come può essere per questo caso, per cui è meglio prevenire con la conversione esplicita dei valori.
Puoi verificare anche con dei semplici log, usando delle stringhe che rappresentano dei valori numerici:
codice:
console.log("1" <= "50"); // true
console.log("5" <= "10"); // false (eh!)
console.log("20" <= "50"); // true
console.log("34" <= "125"); // false (uh!)
console.log("50" <= "100"); // false (ma come!)
console.log("100" <= "50"); // true (coosaa!!!)
console.log("100" <= "1000"); // true
console.log("3456" <= "7"); // true (se... vabbè, qui stiamo dando i numeri)
Come puoi notare, diversi risultati sono del tutto inattesi, da un punto di vista "umano". Verrebbe anche da dire che la cosa sembra capitare in maniera random ma, ovviamente, non è così.
Considera sempre che tu gli stai dicendo di fare un confronto tra due stringhe, anche se stai usando l'operatore "minore o uguale". Questo avviene anche "la prima volta" in cui viene vista la condizione del ciclo (i <= fine).
I due valori in gioco sono delle stringhe. I criceti, in questo caso, non ci pensano troppo e decidono che non c'è bisogno di fare alcuna conversione prima della valutazione, per cui procedono direttamente confrontando le due stringhe... carattere per carattere (finché non si ottiene una certezza del risultato in base alla condizione data).
Perciò, si ha che:
codice:
"1" <= "50" è vero perché il carattere "1" è minore del carattere "5" (il resto non conta);
"5" <= "10" è falso perché il carattere "5" è maggiore del carattere "1" (il resto non conta);
"20" <= "50" è vero perché il carattere "2" e minore del "5" (il resto non conta);
"34" <= "125" è falso perché "3" è maggiore di "1" (il resto non conta);
"50" <= "100" è falso come nel secondo caso;
"100" <= "50" è vero come nel primo caso;
"100" <= "1000" è vero, anche se le prime tre coppie di caratteri sono uguali, un carattere in più risulta maggiore di uno mancante;
"3456" <= "7" è vero perché "3" è minore di "7" (il resto non conta);
Una volta passata la condizione, il ciclo prosegue. Alla seconda iterazione del ciclo, però, la variabile i viene incrementata attraverso l'operatore "++". I criceti ovviamente si troveranno in mano, fino a quel momento, una variabile di tipo stringa ma, dovendola incrementare attraverso un operatore che necessariamente richiede un valore numerico, si vedono costretti a convertire tale valore (e la variabile stessa a cui questo è applicato) in tipo number. Dal secondo giro, quindi, tale variabile sarà e resterà di tipo numerico fino alla conclusione del ciclo.
Chiaramente, dal secondo giro, il valore di i sarà numerico anche nel contesto della condizione (i <= fine). Questo cambierà il criterio di valutazione considerato per il primo giro. Infatti, dal secondo giro in poi, entrambi i valori, sia di i, sia di fine, saranno considerati di tipo number; cioè, dal momento che si ha un conflitto nel tipo di dati da confrontare, i criceti convertiranno i valori, dove possibile, in modo che siano dello stesso tipo; in tal caso la scelta è su valori numerici. Infatti, una volta avviato il ciclo, questo prosegue "normalmente" perché non sono considerati i criteri visti per il confronto di stringhe.
Qui mi interrompo sperando di averti chiarito qualcosa.
Giusto due ultime cose:
Il "+" che ti ho indicato di usare per convertire i valori in tipo numerico, equivale ad usare la funzione Number().
In generale, document.write() è meglio non utilizzarlo, soprattutto quando il caricamento della pagina è stato concluso (come in questo caso), perché questo implica la creazione di un nuovo documento con la conseguente perdita di tutto il markup e dello script presente fino a quel momento nella pagina.
Nel tuo caso, sarebbe meglio usare console.log(), se ti serve giusto attenere un output in fase di debug; oppure usare innerHTML con una cosa tipo document.getElementById("output").innerHTML = risultato, così da mostrare i risultati dentro un apposito contenitore predisposto all'interno della pagina stessa.