Javascript
Il codice va inserito nella pagina almeno nei tag
<script></script>
ma sarebbe più corretto metterlo in:
<script language="javascript" type="text/javascript">
<!--
... codice ...
// -->
</script>
per le pagine HTML (<!-- //--> solo se volete che i browser molto vecchi che non interpretano javascript non diano errore), mentre per quelle XHTML:
<script type="text/javascript">
//<![CDATA[
... codice ...
//]]>
</script>
In ogni caso è possibile inserirlo in un file esterno alla pagina con estensione ".js" che, in oltre, viene inserito nella chache del browser (salvo impostazioni non standard) e quindi fa risparmiare tempo nel download se il codice è utilizzato in più pagine:
<script type="text/javascript" src="/nomefile.js"></script>
Ogni istruzione va separata con il ; (oppure andando a capo).
Tipi di dati
Stringhe
La concatenazione si esprime con il simbolo + e si delimitano con ' (oppure con "").
Carattere | Sigificato |
\b | backspace |
\t | tab orizzontale |
\n | nuova linea |
\r | a capo |
\\ | Backslash |
\" | doppio apice |
\' | apice |
Numeri
Possono essere interi (1234) decimali (separati da punto come 12.34) o esponenziali (12e+34 = 12x10^34).
Operatore | Sigificato |
+ | somma |
- | sottrazione / numero negativo |
* | moltiplicazione |
/ | divisione |
% | modulo (numero % 2 ==0) è la condizione di pari |
Booleani
Sono "true" e "false".
Operatore | Sigificato |
== | uguaglianza |
!= | diversità |
> / >= | maggiore / maggiore o uguale |
< / <= | minore / minore o uguale |
! | NOT |
&& | AND |
|| | OR |
L'ordine di esecuzione è NOT, AND e OR.
Variabili
le variabili non hanno tipo e si dichiarano con la parola chiave "var" ad esempio :
var pippo
possono anche assuemere tipi diversi nel ciclo di vita
pippo = 3;
pippo = 'pluto'
Le operazioni si possono combinare con l'uguale
pippo += 3 vuol dire pippo = pippo +3
e si possono usare anche l'incremento e il decremento
pippo++ vuol dire pippo = pippo +1
pippo-- viol dire pippo = pippo -1
Array
gli array possono definire con
var v = []; oppure var v = new Array(dimensione);
per definire array di più dimensioni occorre per forza fare un ciclo:
var v = []
for (1=0; i<100; i++) v[i] = new array(100);
al contrario di tanti linguaggi gli array in javascript possono essere di elementi di tipo diverso e non contigui.
Parsing tra tipi
I numero sono parsati implicitamente a stringa se sono argomento di funzioni che li usano come parametri.
Per fare il parse di stringhe si usano parseInt() e parseFloat() che restituiscono l'intero o il decimale contenuto nella stringa o NaN (Not a Number) se non lo sono. Se il numero è seguito da una stringa viene ignorato:
parseInt('13pippo') oppure parseInt('13 13') restituiscono entrambe 13 .
Modifica del flusso di esecuzione
Per uscire da un qualsiasi flusso occorre utilizzare il comando"break".
if/else
if (condizione)
{
istruzione 1;
}else{
istruzione 2;
}
switch
switch(numero){
case 1 : istruzione1;
break;
case 2 : istruzione2;
break;
default : istruzioneDefault;
}
for
for(i=0;i<10;i++)
{
istruzione;
}
per le proprietà numerabili:
for(proprietà in oggetto)
{
istruzione;
}
while
while(condizione)
{
istruzione;
}
do/while
do
{
istruzione;
}
while(condizione)
Funzioni e maschere video
Per definire una funzione si utilizza la sintassi:
function nomeFunzione(paramentri)
{
istruzioni;
}
è possibile assegnare dei valori di default ai paramentri, utilizzando l'or logico, quando essi non vengono passati alla funzione:
function nomeFunzione(p)
{
var v = p || "";
}
Le maschere video predefinite più comuni sono:
Funzione | Azione |
alert('stringa') | mostra a video una finestra con la stringa e il bottone "ok" |
confirm('stringa') | mostra a video una finestra con la stringa e i bottoni "ok" e "annulla". Restituisce rispettivamente true o false. |
prompt('stringa') | mostra a video una finestra con la stringa, i bottoni "ok" e "annulla" e una casella testo in cui inserire un valore. Restituisce rispettivamente il valore o Null. |
Un'altra importante funzione è Eval. Il senso è chiaro da questo è sempio:
function valuta(variabile){
alert(variabile + " = " + Eval(variabile));
}
Se vogliamo conoscere il tipo di un oggetto possiamo utilizzare la funzione predefinita typeof.
Per lanciare una funzione ad intervalli regolari si usa la finzione setInterval (ad esempio ogni secondo):
setInterval(nomeFunzione,1000)
clearInterval() annulla la chiamata.
Per eseguire una funzione con un ritardo programmato si può utilizzare la funzione setTimeOut(nomeFunzione,millisecondi).
clearTimeOut() annulla la chiamata.
Per essere sicuri di aver scritto una stringa contenenti caratteri validi per una URL si utilizzano le funzioni encodeURI(stringa) ed decodeURI(stringa).
Programmare a Oggetti
Definizione :
var o = new Object(); oppure var o = {};
Prorpietà :
o.p = nuovoValoreNuovaProprietà;
oppure anche più di uno alla volta:
var o = {
p1= v1,
p2=v2,
....
pN=vN
};
Quando si cerca di leggere il valore di una proprietà che non è stata ancora definita si ottiene il valore (oggetto) Undefined. Per essere sicuri che la proprietà esista è sufficente inserirla come condizione di un if:
if (o.p){cose da fare se esiste}else{cose da fare se non esiste};
Una proprietà può anche essere eliminata con il coando delete.
Operatori:
Gli operatori tra oggetti sono diversi: uguaglianza === ; disuguaglianza !== ;
Metodi:
Si definiscono come le proprietà, mettendo come argomento destro la funzione:
o.m= function(parametro1, paramentro2, ... ) {istruzioni}
all'interno del blocco di istruzioni si può fare riferimento alle proprietà dell'oggetto anteponendo this (this.proprietà)
Costruttori:
Il costruttore di un oggetto è una funzione che ne definisce proprietà e metodi, ututlizzata anche per definire i valori di defoult di essi:
function persona(nome,cognome){
this.nome = nome;
this.congome = cognome;
this.iniziali = function{
var i = "";
if (cognome != "") i = this.cognome.substring(0,1);
if (nome != "") i = this.nome.substring(0,1);
return i;
}
}
Prototipi:
Per limitare il consumo di memoria, non conviene definire nel costruttore le costanti e i metodi comuni a tutte le istanze di un oggetto. Tali elementi si definiscono nel prototipo dell'oggetto, riferendosi all'esempio di prima:
persona.prototype.iniziali = function{
var i = "";
if (cognome != "") i = this.cognome.substring(0,1);
if (nome != "") i = this.nome.substring(0,1);
return i;
}
ha l'effetto di avere una sola copia in memoria della funzione e non un numeo pari alle istanze dell'oggeto persona.
Il prototipo di default, alla creazione, è NULL, ma lo si puo definire come detto pocanzi, ed è possibile anche definire il prototipo del prototipo e così via indefinitamente. E' possibile in oltre, ridefinire prietà e metodi ad ogni livello della catena (prototype chain).
Se il costruttrore di una classe dovesse inizializzare anche delle proprietà/metodi del suo prototipo, dovrebbe contenere al suo interno un'istanza e una chiamata al suo costruttore:
Function oggettoFiglio(p1,p2){
this.v1 = p1;
this.v2 = p2;
this.istanzaOggettoPadre = oggettoPadre;
this.istanzaOggettoPadre(p1,p2);
}
oggettoFiglio.prototype = new oggettoPadre;
in realtà l'ultima riga risulta necessaria per far riconoscere ad una istanza di oggettoFiglio le proprietà/metodi che vengono aggiunti all'oggetto oggettoPadre dopo che detta istanza è stata creata.
Oggetti predefiniti
Tutti gli oggetti sono ereditati da object e quindi posseggono i suoi metodi/proprietà:
constructor;hasOwnProperty(nomeProprietà);isPrototypeOf();toString();toLocaleString();valueOf().
Altri oggetti predefiniti, con le loro proprietà/metodi sono:
Array; boolean; Date; Error; Function; Math; Number; RegExp; String.
Error:
Gli errori possono essere sollevati con la clausola throw:
throw new Error("messagio definito dall'utente");
per gestirlo occorre poi usare try/catch:
try{
funzioneChePotrebbeSollevareLErrore();
}catch(eccezione){
alert("Errore: " + eccezzione.message);
}
RegExp:
serve a verificare la presenza di pattern nelle stringhe. Ha tre metodi: souce è il testo del pattern, exec() esegue il pattern di matchimg mettendo in un array le posizioni delle stringhe corrispondenti al pattern, test() restituisce solo true/false se la stringa contiene il pattern. Per definire un pattern abbiamo due possibilità:
var p = /abc/; oppure var p = new RegExp("abc");
p.test("abcd") restituirà true mentre p.test("acbd") false. p.exec("zzzabczzz").index restituirà 3, mentre se vogliamo sapere tutte le posizioni useremo un ciclo come questo:
var posizione;
var p = /abc/;
while (posizione=p.exec(stringa)){
alert("La posizione è " + posizione.index);
}
Per la definizione dei pattern riferirsi alla pagina dedicata.
String:
Per le stringhe sono definite le funzioni più classiche:
charAt(), charCodeAt(), concat(), fromCharCode(), indexOf() lastIndexOf(), localCompare(), match(), replace(), search(), slice(inizio,fine), split(), substring(inizio,lunghezza), toLowerCase(), toUpperCase().
Bisogna notare che match, search e replace prendono come parametro una espressione regolare, quindi ad esempio è possibile scambiare anche la posizione di pattern in una stringa ecc. (ad es. "pippo pluto".replace(/(\w+) \s (\w+)/, "$2 $1") restituisce "pluto pippo")
In ultimo esistono anche metodi per aggiungere a stringhe TAG HTML :
anchor(nome), big(), blink(), bold(), fixed(), fontcolor(colore), fontsize(dimensione), italics(), link(URL), small(), strike(), sub(), sup().
JSON (JavaScript Object Notation)
E' il modo con cui si possono rappresentae oggetti javascript con una sintassi seplificata, in modo che successivamente sia rappresentabile da una stringa.
Ad esempio l'oggetto:
{
"nome":"pippo",
"cognome":"pluto",
"mioArray":["valore1","valore2"]
}
può essere inserito in una stringa: var stringaOggetto = '{"nome":"pippo","cognome":"pluto","mioArray":["valore1","valore2"]}'
e poi riconvertita a oggetto: var oggettoDaStringa = eval("("+stringaOggetto+")")
L'utilizzo di questa tecnica è tipico in AJAX, ma quando si interpreta una sringa JSON reperita via web conviene utilizzare parseJSON per evitare problemi di sicurezza.
Per approfondimenti si può consultare la pagina dedicata.
DOM (Dinamic Object Model)
Quando un'applicazione espone i propri oggetti all'esterno si dove che ha un proprio Document Object Model, che è sempre navigabile gerarchicamente.
Il W3C ha definito la specifica del dom in 4 livelli:
Level 0: prerequisiti alla specifica;
Level 1: core e HTML;
Level 2: core, views, events, style, traversal and range, HTML;
Level 3: core, load and save, validation;
La tabella delle compatibiltà dei browser alla specifica è reperibile alla URL: http://en.wikipedia.org/wiki/Comparison_of_web_browsers
Gli oggetti principali esposti dall'ambiente di esecuzione di un browser sono:
Navigator
Sceen
Window
Figlio di Window:
History
Location
Document
Figli di Document:
Applets
Anchors
Elements
Images
Links
Forms
Figli di Forms:
Text
Radio
CheckBox
TextArea
Password
Button
Reset
Submit
Select
Figlio di Select:
Options
Generare e modificare i contenuti
Si può usare la funzione Write per aggiungere contenuti nuovi:
document.write('stringa di codice da aggiungere alla pagina');
Per modificare contenuti esistenti conviene definire degli ID per identificare glinelementi della pagina e poi utilizzare la funzione GETELEMENTBYID e ad esempio il metodo INNERHTML se l'oggetto lo prevede (come span, div, ecc.):
<span id="orologio"></span>
Function visualizzaOra(){
document.getElementById("orologio").innerHTML = ""+new Date()
}
Un altro modo per accedere ad alcuni tag specifici della pagina è getElementByTagName che restituirà però tutti i tag della pagina con quel nome, nell'ordine in cui compaiono, in un array, non modificabile o ordinabile .
Ancora, se vogliamo accedere a tutti i tag che gerarchicamente sono sotto un altro possiamo ripetere iterativamente la chiamata partendo da document.childNodes fino ad arrivare alle foglie. Oppure firstChild, lastChild, nextSibling, previousSibling restituiscono rispettivamente il primo o l'ultimo figlio e il successivo o il precedente fratello. Occorre però precisare che sono i childNodes che rispetano la condizione nodeType==1 in quanto ogni cosa è un childnodes ma di tipo diverso come da tabella:
Valore | Sigificato |
1 | elemento |
2 | attributo |
3 | testo |
8 | commento |
9 | documento (solo per document) |
10 | HTML (solo per html) |
Per reperire i valori inseriti nei controlli di un form (vedi pagina dedicata) si usa nomeForm.nomeControllo.value , facendo attenzione però che per il campo upload contiene solo il nome del file e non il suo contenuto (tale limitazione è stata scelta per auemtnare la sicurezza).
Altri contenuti utili
Si può reindirizzare ad un altra pagina con il metodo: window.location.replace('nuovoIdirizzzo').
Per aprire una nuova finestra, chiuderla, dargli il focus o stamparla si possono usare i metodi di window: open(URL), close(), focus(), print().
Per navigare nella history della navigazione possiamo utilizzare i medodi di window.history: back(), forward(), go(numeroPassi)
Si possono ottenere informazioni sull'ambiente di esecuzione del client dalla stringa ottenuta con navigator.userAgent (altre proprietà potrebbero variare tra i browsers)
I fine può essereutile avere informazioni sul video accedendo ai metodi di screen: width, height, top, left.
Gestire gli Eventi
Quando il browser riceve un evento controlla che sulla pagina non ci sia un gestore per esso. La forma canonica è del tipo onNomeEvento = "nomeFunzioneDaLanciare(nomeVariabilediTipoEvent)" dove Event è l'oggetto che rappresenta l'evento, quindi con tutte le sue proprietà e metodi (windows.event per IE6 e precedenti: conviene mettere come prima riga della funzione if !(nomeVariabileDiTipoEvent) nomeVariabileDiTipoEvent = windows.event; in modo da renderla compatibile). Il DOM Level 2 definisce l'interfaccia (cioè il modello) dell'oggetto Event (cioè degli eventi) e la specifica dei sottomoduli di tale interfaccia (HTMLEvent,MouseEvent,UIEvent):
Event che contiene gli attributi/Metodi: bubbles (booleano che indica se si propaga ai livelli superiori), cancelable (booleano), currentTarget (l'elemento che lo ha catturato), eventPhase (CAPTURING_PHASE,AT_TARGET, BUBBLING_PHASE), preventDefault() (metodo che non fa eseguire la funzione associata di default), target (nodo che ha generato l'evento), timestamp, type (nome dell'evento).
UIEvent che contiene la proprietà charCode per mozzilla e keyCode per IE per conoscere il codice del tasto premuto quando lo intercettiamo con i gestori onKeyPress, onKeyDown, onKeyUp.
MouseEvent (sottomodulo di UIEvent) che contiene i seguenti attributi/metodi: altKey, ctrlKey, shiftKey, button(numero) per sapere se erano comtemporaneamente premuti i relativi tasti e screenX e screenY per sapere le coordinate del mouse al momento dell'evento.I gestori di eventi usati per intercettare quelli scatenati dal mouse sono principalmente: onClick, onDblClick, onMouseDown, onMouseUp per intercettare i bottoni e onMouseOver, onMouseMove, OnMouseOut, per intercettarne il movimento sull'elemento.
HMLEvent i cui eventi vengono intercettati di gestori onLoad, onUnload, onResize, onScroll, onError i cui significati sono abbastanza intuitivi.
I campi di inserimento dati hanno generalmente a disposizione i gestori onChange, onFocus, onBlur per cattrurarne il cambiamento, l'acquisizione e la perdita del focus (onSelect per i campi testo). i Form hanno onSubmit e onReset.
Per interrompere la gestione di un evento Mozzilla Firefox utilizza preventDefault() mentre gli altri prevedono che la funzione che gestisce l'evento restituisca false. Per renderlo compatibile conviene quindi usare: try{nomeVariabileDiTipoEvent.preventDefault()}catch(e){return false;}
Gestire i CSS
I valori dello style di un elemento sono modificabili come proprietà di esso ma con l'accortezza che: se il nome della proprietà CSS aveva il "-" in javascript si leva e si sostituisce con la lettra maiuscola sulla prima lettera della parola successiva:
Ad esempio <tag style="font-size:1px" /> diventa tag.style.fontSize = "1px"
I valori numerici della proprietà CSS sono comunque stringhe in Javascript.